C#中Array.Sort() 快速排序-源码分析

快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。

该方法的基本思想是:

1.先从数列中取出一个数作为基准数。

2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.再对左右区间重复第二步,直到各区间只有一个数。

之前提到过,Array的Sort()方法采用的是快速排序方法,通过使用.NET Reflector对程序集mscorlib进行解析,分析源码。

首先安装.NET Reflector,打开VS2010,新建一个项目,键入如下代码:

string [] names = {"wang", "li", "liu", "zhao"};

Array.Sort(names);

在Sort上右键,选择“Open in .NET Reflector Desktop”,便会自动打开.NET Reflector:

public static void Sort(T[] array)

{ if (array == null)

{

throw new ArgumentNullException("array");

}

Sort(array, array.GetLowerBound(0), array.Length, null);

}

点击Sort(array, array.GetLowerBound(0), array.Length, null):

public static void Sort(T[] array, int index, int length, IComparer comparer)

{ if (array == null)

{ throw new ArgumentNullException("array");

}

if ((index < 0) || (length < 0))

{ throw new ArgumentOutOfRangeException((length < 0) ? "length" : "index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));

}

if ((array.Length - index) < length)

{

throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));

}

if ((length > 1) && (((comparer != null) && (comparer != Comparer.Default)) || !TrySZSort(array, null, index, (index + length) - 1)))

{

ArraySortHelper.Default.Sort(array, index, length, comparer);

}

}

点击 ArraySortHelper.Default.Sort(array, index, length, comparer):

internal class ArraySortHelper : IArraySortHelper

{

// Fields

private static IArraySortHelper defaultArraySortHelper;

// Methods

public ArraySortHelper();

public int BinarySearch(T[] array, int index, int length, T value, IComparer comparer);

[SecuritySafeCritical]

private static IArraySortHelper CreateArraySortHelper();

internal static int InternalBinarySearch(T[] array, int index, int length, T value, IComparer comparer);

internal static void QuickSort(T[] keys, int left, int right, IComparer comparer);

public void Sort(T[] keys, int index, int length, IComparer comparer);

private static void SwapIfGreaterWithItems(T[] keys, IComparer comparer, int a, int b);

// Properties

public static IArraySortHelper Default { get; }

}

此时,可以看到快速排序,点击QuickSort,得到快速排序的源码:

internal static void QuickSort(T[] keys, int left, int right, IComparer comparer)

{

do

{

int a = left;

int b = right;

int num3 = a + ((b - a) >> 1);

ArraySortHelper.SwapIfGreaterWithItems(keys, comparer, a, num3);

ArraySortHelper.SwapIfGreaterWithItems(keys, comparer, a, b);

ArraySortHelper.SwapIfGreaterWithItems(keys, comparer, num3, b);

T y = keys[num3];

do

{

while (comparer.Compare(keys[a], y) < 0)

{

a++;

}

while (comparer.Compare(y, keys[b]) < 0)

{

b--;

}

if (a > b)

{

break;

}

if (a < b)

{

T local2 = keys[a];

keys[a] = keys[b];

keys[b] = local2;

}

a++;

b--;

}

while (a <= b);

if ((b - left) <= (right - a))

{

if (left < b)

{

ArraySortHelper.QuickSort(keys, left, b, comparer);

}

left = a;

}

else

{

if (a < right)

{

ArraySortHelper.QuickSort(keys, a, right, comparer);

}

right = b;

}

}

while (left < right);

}

internal static void QuickSort(T[] keys, int left, int right, IComparer comparer)

{

do

{

int a = left;

int b = right;

int num3 = a + ((b - a) >> 1);

ArraySortHelper.SwapIfGreaterWithItems(keys, comparer, a, num3);

ArraySortHelper.SwapIfGreaterWithItems(keys, comparer, a, b);

ArraySortHelper.SwapIfGreaterWithItems(keys, comparer, num3, b);

T y = keys[num3];

do

{

while (comparer.Compare(keys[a], y) < 0)

{

a++;

}

while (comparer.Compare(y, keys[b]) < 0)

{

b--;

}

if (a > b)

{

break;

}

if (a < b)

{

T local2 = keys[a];

keys[a] = keys[b];

keys[b] = local2;

}

a++;

b--;

}

while (a <= b);

if ((b - left) <= (right - a))

{

if (left < b)

{

ArraySortHelper.QuickSort(keys, left, b, comparer);

}

left = a;

}

else

{

if (a < right)

{

ArraySortHelper.QuickSort(keys, a, right, comparer);

}

right = b;

}

}

while (left < right);

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-24 12:18:56

C#中Array.Sort() 快速排序-源码分析的相关文章

Java中arraylist和linkedlist源码分析与性能比较

Java中arraylist和linkedlist源码分析与性能比较 1,简介 在java开发中比较常用的数据结构是arraylist和linkedlist,本文主要从源码角度分析arraylist和linkedlist的性能. 2,arraylist源码分析 Arraylist底层的数据结构是一个对象数组,有一个size的成员变量标记数组中元素的个数,如下图: * The array buffer into which the elements of the ArrayList are sto

关于java中ReentrantLock类的源码分析以及总结与例子

一,官方描述 关于ReentrantLock的官方描述,英文的就不贴出来了,这里我只贴出我自己翻译的描述: reentrant是一个跟synchronized具有相同行为和语义的持有锁来访问方法和语句的互斥锁,但是reentrant还拥有被扩展的能力. ReentrantLock会被线程拥有并且持续锁定,不会解锁.线程调用lock()方法返回后,则成功持有锁,否则这个锁正在被另一个线程所持有,只能等待另一个线程释放锁,如果当前线程拥有了锁,则调用lock()方法会立即返回,这个状态可以通过isH

JDK中String类的源码分析(二)

1.startsWith(String prefix, int toffset)方法 包括startsWith(*),endsWith(*)方法,都是调用上述一个方法 1 public boolean startsWith(String prefix, int toffset) { 2 char ta[] = value; 3 int to = toffset; 4 char pa[] = prefix.value; 5 int po = 0; 6 int pc = prefix.value.l

Netty中NioEventLoopGroup的创建源码分析

NioEventLoopGroup的无参构造: 1 public NioEventLoopGroup() { 2 this(0); 3 } 调用了单参的构造: 1 public NioEventLoopGroup(int nThreads) { 2 this(nThreads, (Executor)null); 3 } 继续看到双参构造: 1 public NioEventLoopGroup(int nThreads, Executor executor) { 2 this(nThreads,

ThreadPoolExecutor的应用和实现分析(中)—— 任务处理相关源码分析

转自:http://www.tuicool.com/articles/rmqYjq 前面一篇文章从Executors中的工厂方法入手,已经对ThreadPoolExecutor的构造和使用做了一些整理.而这篇文章,我们将接着前面的介绍, 从源码实现上对ThreadPoolExecutor在任务的提交.执行,线程重用和线程数维护等方面做下分析. 0.    ThreadPoolExecutor类的声明属性变量分析 public class ThreadPoolExecutor extends Ab

golang中container/heap包源码分析

学习golang难免需要分析源码包中一些实现,下面就来说说container/heap包的源码 heap的实现使用到了小根堆,下面先对堆做个简单说明 1. 堆概念 堆是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于(或不小于)其左孩子和右孩子节点的值. 最大堆和最小堆是二叉堆的两种形式. 最大堆:根结点的键值是所有堆结点键值中最大者. 最小堆:根结点的键值是所有堆结点键值中最小者. 2. heap 树的最小元素在根部,为index 0. heap包对任意实现了heap接口的类型提供

golang中container/list包源码分析

golang源码包中container/list实际上是一个双向链表 提供链表的一些基本操作,下面就结合定义和接口进行下说明 1. 定义 // Element is an element of a linked list. type Element struct { // Next and previous pointers in the doubly-linked list of elements. // To simplify the implementation, internally a

【Flume】flume中拦截器的源码分析,以TimestampInterceptor为例

本文将以TimestampInterceptor为例来分析一下flume中拦截器的工作原理 首先来看下改拦截器的实现结构 1.实现了Interceptor接口 该接口的方法定义如下: public void initialize(); public Event intercept(Event event); public List<Event> intercept(List<Event> events); public void close(); /** Builder imple

word2vec中 distence.c 文件源码分析

#include <stdio.h> #include <string.h> #include <math.h> //#include <malloc.h> #include <stdlib.h> const long long max_size = 2000; // max length of strings const long long N = 5; // number of closest words that will be shown