排序陷阱 List.Sort Linq.OrderBy


C#框架里面主要提供了兩種排序方式:Array.Sort Linq.Orderby。
List.Sort排序簡介
有許多猿猴對Sort原理進行了剖析,Sort排序實際上分為兩部分,基於ClR內部排序,基於算法:深度限制快速排序(DepthLimitQuickSort)。基於CLR排序是針對內置類型排序;深度限制快速排序是先快速排序,達到一定深度時,更改為堆排序。核心代碼如下:
private void DepthLimitedQuickSort(int left, int right, int depthLimit)
{
do
{
if (depthLimit == 0)
{
try
{
this.Heapsort(left, right);
break;
}
catch (IndexOutOfRangeException)
{
throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer",
new object[] { this.comparer }));
}
catch (Exception innerException)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), innerException);
}
}
int num = left;
int num2 = right;
int median = Array.GetMedian(num, num2);
try
{
this.SwapIfGreaterWithItems(num, median);
this.SwapIfGreaterWithItems(num, num2);
this.SwapIfGreaterWithItems(median, num2);
}
catch (Exception innerException2)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), innerException2);
}
object obj = this.keys[median];
do
{
try
{
while (this.comparer.Compare(this.keys[num], obj) < 0)
{
num++;
}
while (this.comparer.Compare(obj, this.keys[num2]) < 0)
{
num2--;
}
}
catch (IndexOutOfRangeException)
{
throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer",
new object[] { this.comparer }));
}
catch (Exception innerException3)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), innerException3);
}
if (num > num2)
{
break;
}
if (num < num2)
{
object obj2 = this.keys[num];
this.keys[num] = this.keys[num2];
this.keys[num2] = obj2;
if (this.items != null)
{
object obj3 = this.items[num];
this.items[num] = this.items[num2];
this.items[num2] = obj3;
}
}
num++; num2--;
}
while (num <= num2);
depthLimit--;
if (num2 - left <= right - num)
{
if (left < num2)
{
this.DepthLimitedQuickSort(left, num2, depthLimit);
}
left = num;
}
else
{
if (num < right)
{
this.DepthLimitedQuickSort(num, right, depthLimit);
}
right = num2;
}
} while (left < right);
}

 

說明:
  1  使用Sort排序時,有可能會打破數組列表的基本順序。在數據相同的項具有不同含義時,不能使用Sort排序。
  2 Array.Sort和List.Sort采用的是同一個排序方法。
 
Linq.Orderby排序簡介
Orderby使用的快速排序,它不會破壞數組列表的基本順序。排序核心代碼如下:
internal int[] Sort(TElement[] elements, int count)
{
this.ComputeKeys(elements, count);
int[] map = new int[count];
for (int index = 0; index < count; ++index)
map[index] = index;
this.QuickSort(map, 0, count - 1); return map;
}
 
private void QuickSort(int[] map, int left, int right)
{
do
{
int left1 = left;
int right1 = right;
int index1 = map[left1 + (right1 - left1 >> 1)];
while (true)
{
do
{
if (left1 >= map.Length || this.CompareKeys(index1, map[left1]) <= 0)
{
while (right1 >= 0 && this.CompareKeys(index1, map[right1]) < 0)
--right1;
if (left1 <= right1)
{
if (left1 < right1)
{
int num = map[left1]; map[left1] = map[right1]; map[right1] = num;
}
++left1;
--right1;
}
else break;
}
else goto label_1;
} while (left1 <= right1); break;
label_1: ++left1;
}
if (right1 - left <= right - left1)
{
if (left < right1)
this.QuickSort(map, left, right1);
left = left1;
} else {
if (left1 < right)
this.QuickSort(map, left1, right);
right = right1;
}
} while (left < right);
}

 

說明:
1 一般情況下,業務相關的排序過程是不存在相同情況的。所以這個排序陷阱可以忽略
2 如果需要多個階段的排序實現最終邏輯,且存在排序的位置相同情況時,不建議使用Array.Sort


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM