一、奇怪的现象
研究快速排序很久了,发现一个古怪的实情:这算法描述起来很简单,写一个正确的出来实在不容易.写一个优秀的快速排序算法更是难上加难.
也难怪该算法提出来过了很久才有人写出一个正确的算法,过了很久才优秀的版本出来.
二、原理描述
- 从数列中挑出一个元素,称为 "基准"(pivot),
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序.
三、最容易让人理解的版本
一个List形式的数组,找到其中的第一个做基准,遍历剩下的数据,然后创建两个左右List,大的放右边,小的放左边.然后对左右List各自进行如上操作.......
详情见代码
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
|
四、正确但不优化的版本
using System;
namespace Sort
{
class Program
{
static void Main(string[] args)
{
string result = string.Empty;
int[] unsort = { 2, 0, 3, 7, 5,6 };
//快速排序
QuickSort(unsort, 0, unsort.Length - 1);
Console.ReadLine();
}/// <summary>
/// 调用快速排序算法
/// </summary>
/// <param name="unsort">待排序的整形数组</param>
/// <param name="left">左边起始点</param>
/// <param name="right">右边结束点</param>
public static void QuickSort(int[] unsort, int left, int right)
{
if (left < right)
{
//获取一次排序的中间索引位置
int midPosition = GetSplitNum(unsort, left, right);//递归实现
QuickSort(unsort, left, midPosition - 1);
QuickSort(unsort, midPosition + 1, right);
}
}static int ORDER_INDEX=1;
/// <summary>
/// 获取一次排序的中间索引位置
/// </summary>
/// <param name="unsort">待排序的整形数组</param>
/// <param name="left">左边起始点</param>
/// <param name="right">右边结束点</param>
public static int GetSplitNum(int[] unsort, int left, int right)
{
int splitNum = unsort[left];
while (left < right)
{
/**
* 从右端开始比较
* (1)假如从右端过来的数比分隔数要大,则不用处理
* (2)假如从右端过来的数比分隔数要小,则需要挪到分隔线左边
* */
while (left < right && splitNum <= unsort[right])
{
right--;
}
unsort[left] = unsort[right];
GetPrint(unsort);
/**
* 从从端开始比较
* (1)假如从左端过来的数比分隔数要小,则不用处理
* (2)假如从左端过来的数比分隔数要大,则需要挪到分隔线右边
* */
while (left < right && splitNum >= unsort[left])
{
left++;
}
unsort[right] = unsort[left];
GetPrint(unsort);
}
//一趟比较之后,分隔数的位置就可以确认起来
unsort[left] = splitNum;
Console.WriteLine(string.Format("第{0}轮排序完毕",(ORDER_INDEX++)));
GetPrint(unsort);
return left;
}/// <summary>
/// 打印输出结果
/// </summary>
/// <param name="unsort">数据</param>
public static string GetPrint(int[] unsort)
{
string result = string.Empty;
foreach (int n in unsort)
{
if (!string.IsNullOrEmpty(result))
{
result += string.Format("->{0}", n);
}
else
{
result = string.Format("{0}", n);
}
}
Console.WriteLine(result);
return result;
}
public static string GetPrint(int[] unsort,int replaceIndex)
{
string result = string.Empty;
foreach (int n in unsort)
{
if (!string.IsNullOrEmpty(result))
{
result += string.Format("->{0}", n);
}
else
{
result = string.Format("{0}", n);
}
}
Console.WriteLine(result+" ==>"+replaceIndex);
return result;
}
}
}
关于快速排序算法(一个90%的人都不懂其原理、99.9%的人都不能正常写出来的算法.),布布扣,bubuko.com