C#实现快速排序
Posted WEREWOLFGHOST
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#实现快速排序相关的知识,希望对你有一定的参考价值。
网上很多关于快速排序的教程,嗯,不错,版本也很多,有的试了一下还报错。。呵呵
于是乎低智商的朕花了好几天废了8张草稿纸才弄明白。。
快速排序的采用的分治啊挖坑填数啊之类的网上到处都是,具体过程自己百度吧,这里就讲讲我自己写的代码。还有,快排是一种不稳定的排序算法,就是说,当整个数列是无序状态时,效率高,但是,当把一个从大到小的通过排序转成从小到大的,那就呵呵了,随时StackOverflow。。
OK,先上代码(排序结果是从小到大)
1 static void QuickSort(int[] num, int left, int right) 2 { 3 if (left >= right) 4 return; 5 6 int key = num[left]; 7 int i = left; 8 int j = right; 9 10 while (i < j) 11 { 12 while (i < j && key < num[j]) 13 j--; 14 if (i >= j) 15 { 16 num[i] = key; 17 break; 18 } 19 num[i] = num[j]; 20 21 while (i < j && key >= num[i]) 22 i++; 23 if (i >= j) 24 { 25 num[i] = key; 26 break; 27 } 28 num[j] = num[i]; 29 } 30 num[i] = key; 31 32 QuickSort(num, left, i - 1); 33 QuickSort(num, i + 1, right); 34 }
参数中的num就不用说了吧,left和right分别代表排序待排序数组的开始和结尾的索引,当然默认排序整个数组的话就:
QuickSort(a, 0, a.Length - 1);
假设待排序数组是a,排序索引是0到最后一项的元素。
快排使用分治,选取一个关键值key(代码中的第6行,并且默认使用待排序数组的第一个值),把比它大的和比它小的分别放在两边。
具体就是先从数组右边(j值记录的索引)开始找比key小的数,对应代码的12、13行,至于为什么要i < j,呵呵,待会儿说。
循12行环的意义是,如果当前num[j]比key大,j就自减,直到key>num[j]就找到了比key小或相等的数了呗。
又由于排序的数千变万化,所以有的情况下j一路减下去或记录左边索引的i一路加上去,就有可能i>=j,于是就有了10、12、14、21、23行判断i和j关系的语句了,因为如果i都>=j了,就表示分完了啊。
于是先假设i一直<j,通过12行的循环找到了比key小或等于的值,就把左右的数交换,不用担心key不见,因为有第6行。。
之后又通过21行的循环找比key大的值,再在28行交换。这样下来10行的大循环完了之后,数组就留了一个“空位”(这个“空位”当然有数,只是它应该被key填充),再在30行用key填充。
之后31、32行递归(别说你不知道啥意思),再对key两边的数进行排序。
排序完成后,i值就对应key的索引,所以递归调用的参数就那样填。。
以上纯属个人理解,有错误的地方还请指出!
以上是关于C#实现快速排序的主要内容,如果未能解决你的问题,请参考以下文章
C# 各种内部排序方法的实现(直接插入排序希尔排序冒泡排序快速排序直接选择排序堆排序归并排序基数排序)