【发布时间】:2016-04-05 15:24:00
【问题描述】:
我在如何正确排序 .NET 2.0 中的字典时遇到问题。这段代码有点旧(2002 年或其他),它可以工作,但不是我想要的方式。由于 AvailableFlights 字典可能非常庞大,因此这种排序功能可能会花费大量时间,而客户没有这么多时间。
任何人都知道如何做到这一点,我知道的唯一方法是添加 orderby 或其他东西,因为 2002 年我在花园里玩耍。
注意:这是一个正在进行的网站的代码,问题是,我的老板想要这个更快,但我无法对项目进行重大更改。
排序函数本身是这样工作的:有一个字典 AvailableFlight,其中包含 Flight 对象(带有 TotalPrice)。这来自外部来源,因此预过滤不是一种选择。要实现的目标是将 TotalPrice 最低的航班排在首位。
对于不知道我在问什么的人,在我的项目中有一个字典,其中包含存储为具有相应整数键的对象的飞行对象。 飞行对象有一个属性Totalprice,需要ASC进行排序。我提供的代码会出现这种情况,仅处理这段代码的时间大约需要 30 秒或更长时间,这是不可接受的。所以问题是,我该如何改进这一点,以减少处理时间。
public void SortFlightResult()
{
//bool to check sorting is done or not
bool blSort = true;
//bool to stay in while or not
bool blWhileSort = true;
while (blWhileSort)
{
//check the availableFlights
foreach (int i in AvailableFlights.Keys)
{
foreach (int j in AvailableFlights.Keys)
{
//if id j is greater then id i and price is less then j must be in place of i
if ((AvailableFlights[j].TotalPrice < AvailableFlights[i].TotalPrice) && (j > i))
{
//set temperary AvailableFlight object
AvailableFlight avTemp = new AvailableFlight();
avTemp = AvailableFlights[i];
AvailableFlights[i] = AvailableFlights[j];
//keep id of the i (if j.id = 3 and i.id = 2) replace i with j but let id = 2
AvailableFlights[i].ID = i;
AvailableFlights[j] = avTemp;
AvailableFlights[j].ID = j;
//set bool fase so we know sort is not done
blSort = false;
//end both foreach loop so we can start over from the top of availableFlights
goto endLoop;
}
}
}
endLoop:
//if true --> availableFlights is sorted set bool while false to quit the function
if (blSort)
{
blWhileSort = false;
}
else
{//set bool sort back to true
blSort = true;
}
}
}
抛开所有的废话*t,感谢@D Stanley 的有用评论。 我将算法更改为 堆排序,处理排序的时间从大约 30 秒 减少到 400 毫秒,真的很高兴!
对堆排序代码感兴趣的人:
堆排序
public void HeapSort()
{
Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();
//Build Max-Heap
Dictionary<int, AvailableFlight> input = AvailableFlights;
int heapSize = input.Keys.Count;
for (int p = (heapSize -1) /2; p >= 0; p--)
{
MaxHeapify(AvailableFlights, heapSize, p);
}
for (int i = AvailableFlights.Count - 1; i > 0; i--)
{
//Swap
AvailableFlight temp = input[i];
input[i] = input[0];
input[0] = temp;
heapSize--;
MaxHeapify(AvailableFlights, heapSize, 0);
}
watch.Stop();
Debug.WriteLine("SortFlightResult 2: " + watch.ElapsedMilliseconds);
}
MaxHeapify
private static void MaxHeapify(Dictionary<int, AvailableFlight> input, int heapSize, int index)
{
int left = (index + 1) * 2 - 1;
int right = (index + 1) * 2;
int largest = 0;
if (left < heapSize && input[left].TotalPrice > input[index].TotalPrice)
{
largest = left;
}
else
{
largest = index;
}
if (right < heapSize && input[right].TotalPrice > input[largest].TotalPrice)
{
largest = right;
}
if (largest != index)
{
AvailableFlight temp = input[index];
input[index] = input[largest];
input[largest] = temp;
MaxHeapify(input, heapSize, largest);
}
}
【问题讨论】:
-
字典没有排序——如果你想要一个项目列表并且能够重新排序项目使用
List而不是Dictionary -
@Sinatr 即使使用已排序的字典,代码也会重新组织项目。没有迹象表明这里使用了字典的好处。
-
您使用
goto这一事实表明您没有使用正确的过程或数据结构。 -
改变排序算法会被认为是“巨大的改变”吗?您可以对 sorting algorithms 进行一些研究,看看根据您的起始数据是什么不同的算法可能更快。
标签: c# .net sorting dictionary