使用JetBrains的DotPeek工具能够方便地查看.net的部分源代码。于是看了一下.NET的内部是怎样实现排序的算法。

在System.Collections.Generic 命名空间下能够看到ArraySortHelper<T>的实现。

public void Sort(T[] keys, int index, int length, IComparer<T> comparer)
{
try
{
if (comparer == null)
comparer = (IComparer<T>) Comparer<T>.Default;
if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
ArraySortHelper<T>.IntrospectiveSort(keys, index, length, comparer);
else
ArraySortHelper<T>.DepthLimitedQuickSort(keys, index, length + index - 1, comparer, 32);
}
catch (IndexOutOfRangeException ex)
{
IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer((object) comparer);
}
catch (Exception ex)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), ex);
}
}

发如今.NET4.5以上的版本号,開始使用一种叫做 Introspective Sort的排序方法。

 internal static void IntrospectiveSort(T[] keys, int left, int length, IComparer<T> comparer)
{
if (length < 2)
return;
ArraySortHelper<T>.IntroSort(keys, left, length + left - 1, 2 * IntrospectiveSortUtilities.FloorLog2(keys.Length), comparer);
} private static void IntroSort(T[] keys, int lo, int hi, int depthLimit, IComparer<T> comparer)
{
for (; hi > lo; {
int num;
hi = num - 1;
}
)
{
int num = hi - lo + 1;
if (num <= 16)
{
if (num == 1)
break;
if (num == 2)
{
ArraySortHelper<T>.SwapIfGreater(keys, comparer, lo, hi);
break;
}
else if (num == 3)
{
ArraySortHelper<T>.SwapIfGreater(keys, comparer, lo, hi - 1);
ArraySortHelper<T>.SwapIfGreater(keys, comparer, lo, hi);
ArraySortHelper<T>.SwapIfGreater(keys, comparer, hi - 1, hi);
break;
}
else
{
ArraySortHelper<T>.InsertionSort(keys, lo, hi, comparer);
break;
}
}
else if (depthLimit == 0)
{
ArraySortHelper<T>.Heapsort(keys, lo, hi, comparer);
break;
}
else
{
--depthLimit;
num = ArraySortHelper<T>.PickPivotAndPartition(keys, lo, hi, comparer);
ArraySortHelper<T>.IntroSort(keys, num + 1, hi, depthLimit, comparer);
}
}
} private static int PickPivotAndPartition(T[] keys, int lo, int hi, IComparer<T> comparer)
{
int index = lo + (hi - lo) / 2;
ArraySortHelper<T>.SwapIfGreater(keys, comparer, lo, index);
ArraySortHelper<T>.SwapIfGreater(keys, comparer, lo, hi);
ArraySortHelper<T>.SwapIfGreater(keys, comparer, index, hi);
T obj = keys[index];
ArraySortHelper<T>.Swap(keys, index, hi - 1);
int i = lo;
int j = hi - 1;
while (i < j)
{
do
;
while (comparer.Compare(keys[++i], obj) < 0);
do
;
while (comparer.Compare(obj, keys[--j]) < 0);
if (i < j)
ArraySortHelper<T>.Swap(keys, i, j);
else
break;
}
ArraySortHelper<T>.Swap(keys, i, hi - 1);
return i;
}

而.NET4.5下面使用的是还有一种排序的方案。

在排序的数字小于16个的时候,直接使用插入排序。

private static void InsertionSort(T[] keys, int lo, int hi, IComparer<T> comparer)
{
for (int index1 = lo; index1 < hi; ++index1)
{
int index2 = index1;
T x;
for (x = keys[index1 + 1]; index2 >= lo && comparer.Compare(x, keys[index2]) < 0; --index2)
keys[index2 + 1] = keys[index2];
keys[index2 + 1] = x;
}
}

而假设大于16个的时候,且当递归深度在32次之内的话(也就是数字小于4GB的数量时),使用高速排序。

internal static void DepthLimitedQuickSort(T[] keys, int left, int right, IComparer<T> comparer, int depthLimit)
{
while (depthLimit != 0)
{
int index1 = left;
int index2 = right;
int index3 = index1 + (index2 - index1 >> 1);
ArraySortHelper<T>.SwapIfGreater(keys, comparer, index1, index3);
ArraySortHelper<T>.SwapIfGreater(keys, comparer, index1, index2);
ArraySortHelper<T>.SwapIfGreater(keys, comparer, index3, index2);
T obj1 = keys[index3];
do
{
while (comparer.Compare(keys[index1], obj1) < 0)
++index1;
while (comparer.Compare(obj1, keys[index2]) < 0)
--index2;
if (index1 <= index2)
{
if (index1 < index2)
{
T obj2 = keys[index1];
keys[index1] = keys[index2];
keys[index2] = obj2;
}
++index1;
--index2;
}
else
break;
}
while (index1 <= index2);
--depthLimit;
if (index2 - left <= right - index1)
{
if (left < index2)
ArraySortHelper<T>.DepthLimitedQuickSort(keys, left, index2, comparer, depthLimit);
left = index1;
}
else
{
if (index1 < right)
ArraySortHelper<T>.DepthLimitedQuickSort(keys, index1, right, comparer, depthLimit);
right = index2;
}
if (left >= right)
return;
}
ArraySortHelper<T>.Heapsort(keys, left, right, comparer);
}

而假设大于4GB的数量时,使用堆排序。

private static void Heapsort(T[] keys, int lo, int hi, IComparer<T> comparer)
{
int n = hi - lo + 1;
for (int i = n / 2; i >= 1; --i)
ArraySortHelper<T>.DownHeap(keys, i, n, lo, comparer);
for (int index = n; index > 1; --index)
{
ArraySortHelper<T>.Swap(keys, lo, lo + index - 1);
ArraySortHelper<T>.DownHeap(keys, 1, index - 1, lo, comparer);
}
} private static void DownHeap(T[] keys, int i, int n, int lo, IComparer<T> comparer)
{
T x = keys[lo + i - 1];
for (; i <= n / 2; {
int num;
i = num;
}
)
{
num = 2 * i;
if (num < n && comparer.Compare(keys[lo + num - 1], keys[lo + num]) < 0)
++num;
if (comparer.Compare(x, keys[lo + num - 1]) < 0)
keys[lo + i - 1] = keys[lo + num - 1];
else
break;
}
keys[lo + i - 1] = x;
}

最后,附上swap函数的实现:

private static void SwapIfGreater(T[] keys, IComparer<T> comparer, int a, int b)
{
if (a == b || comparer.Compare(keys[a], keys[b]) <= 0)
return;
T obj = keys[a];
keys[a] = keys[b];
keys[b] = obj;
} private static void Swap(T[] a, int i, int j)
{
if (i == j)
return;
T obj = a[i];
a[i] = a[j];
a[j] = obj;
}

.NET源代码的内部排序实现的更多相关文章

  1. 七种机器内部排序的原理与C语言实现,并计算它们的比较次数与移动次数。

    内部排序是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列. 排序是计算机程序设计中的一种重要操作,其功能是对一个数据元素集合或序列重新排列成一个按数据元素某个相知有序的序列.排序分为 ...

  2. 七内部排序算法汇总(插入排序、Shell排序、冒泡排序、请选择类别、、高速分拣合并排序、堆排序)

    写在前面: 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的随意序列,又一次排列成一个按keyword有序的序列.因此排序掌握各种排序算法很重要. 对以下介绍的各个排序,我们假定全部排 ...

  3. C++ 内部排序(一)

    先讲两个概念,所谓内部排序,指待排序的节点均存储在内存中.所谓排序的稳定性,指排序后,值相等的两个元素原来相对的位置是否发生变化了.举个例子. 待排序列:3(1),1,5,3(2)  稳定排序:1,3 ...

  4. 排序算法练习--JAVA(:内部排序:插入、选择、冒泡、快速排序)

    排序算法是数据结构中的经典算法知识点,也是笔试面试中经常考察的问题,平常学的不扎实笔试时候容易出洋相,回来恶补,尤其是碰到递归很可能被问到怎么用非递归实现... 内部排序: 插入排序:直接插入排序 选 ...

  5. 内部排序->其它->地址排序(地址重排算法)

    文字描述 当每个记录所占空间较多,即每个记录存放的除关键字外的附加信息太大时,移动记录的时间耗费太大.此时,就可以像表插入排序.链式基数排序,以修改指针代替移动记录.但是有的排序方法,如快速排序和堆排 ...

  6. 内部排序->基数排序->链式基数排序

    文字描述 基数排序是和前面各类排序方法完全不相同,前面几篇文章介绍的排序算法的实现主要是通过关键字间的比较和移动记录这两种操作,而实现基数排序不需要进行记录关键字间的比较.基数排序是一种借助多关键字排 ...

  7. 内部排序->归并排序->2-路归并排序

    文字描述 假设初始序列有n个记录,则可看成是n个有序的字序列,每个字序列的长度为1,然后两两归并,得到[n/2]个长度为2或1的有序子序列:再两两归并,…, 如此重复,直到得到一个长度为n的有序序列为 ...

  8. 内部排序比较(Java版)

    内部排序比较(Java版) 2017-06-21 目录 1 三种基本排序算法1.1 插入排序1.2 交换排序(冒泡)1.3 选择排序(简单)2 比较3 补充3.1 快速排序3.2 什么是桶排序3.3 ...

  9. Java实现各种内部排序算法

    数据结构中常见的内部排序算法: 插入排序:直接插入排序.折半插入排序.希尔排序 交换排序:冒泡排序.快速排序 选择排序:简单选择排序.堆排序 归并排序.基数排序.计数排序 直接插入排序: 思想:每次将 ...

随机推荐

  1. state-of-the-art implementations related to visual recognition and search

    http://rogerioferis.com/VisualRecognitionAndSearch2014/Resources.html Source Code Non-exhaustive lis ...

  2. 如此的相似,不能-------Day84

    生活中我们会遇到一些相似事儿,它可能是一个项目,我发现,你失去非常相似,其结果是不,它可以是人.你认为你一直在等待的是他(她),终于可以找到,只需简单地认为.正是这样相似. js和java语言中有不少 ...

  3. 网络广告公司的恐慌 XSS广告终结者(html5新特性)

    人们在平时网络冲浪的时候,有时候会发现当前网站有很多莫名其妙的广告,这些广告会被导向到站外. 这些广告可能是你安装了一些免费网络软件后强制安装的浏览器插件导致的. 譬如chrome浏览器:

  4. hdu4570Multi-bit Trie (间隙DP)

    Problem Description IP lookup is one of the key functions of routers for packets forwarding and clas ...

  5. 普及windows流氓程序和监控软件

    win7下载更改后无黑屏windows7激活程序v1.0 一个立即安装 美女主播节目,和流行的色情垃圾邮件 安装程序,结果装了很多垃圾节目,输入.日历.文件等. 重新启动机器后,,会弹出广告. .他的 ...

  6. UVA662- Fast Food

    题意:在一条公路上,有n个酒店,要建造k个供给站(建造在酒店所在的位置),给出酒店的位置,求怎么样建造供给站才干使得每一个酒店都能得到服务且所要走的路程最短. 思路:在i到j酒店建立一个供给站,要使得 ...

  7. JSF+EJB+JPA总体思路

    前言: JSF+EJB+JPA 其实我并没有想象中的难,只是想做好,建立在正确的地方应用,真正的困难. 良好的技术,在错误的地方做应用,这是唯一能够被垃圾. 用. 重量级企业应用能够使用这个主要的3层 ...

  8. 五通信算法:五种编码增益比较matlab模拟

    1. 卷积编码增益性能.BER 信道环境:AWGN 信噪比SNR :0:0.1:6 MATALB仿真架构:源比特 +卷积码 +BPSK +AWGN +Viterbi +BER 说明:卷积编码,不同的R ...

  9. PHP于Post和Get得到的数据写入到文件中

    有时Post要么Get越过那我们不知道什么样的形状数据,它可以是JSON格风格或只是简单地通过数据.这一次,我们能够把他写的文字,传过来的数据是什么格式了. $val = ""; ...

  10. JAVA解决大数

    主题链接:CLICK HERE~ 有了Java求解大数变得如此简单,以后再也不用操心大数模板了.哦啦啦啦. import java.math.BigInteger; import java.math. ...