快速排序.gif
快速排序星压,也叫分治法杭煎,是9種經(jīng)典排序方法中效率最高的咐汞。
原理:以升序?yàn)槔?/strong>,每輪比較之后瓣颅,保證基準(zhǔn)值左邊的數(shù)比它小,右邊的數(shù)比它大譬正。
-
思路:使用分治法(Divide and conquer)策略來把一個(gè)序列(list)分成兩個(gè)子序列(sub-list)宫补。
(3.1)從數(shù)列中挑出一個(gè)元素,稱為"基準(zhǔn)"(pivot)曾我。
(3.2)重新排列數(shù)列粉怕,所有元素比基準(zhǔn)值小的擺放在基準(zhǔn)左邊,所有元素比基準(zhǔn)值大的擺放在基準(zhǔn)右邊抒巢。
......
(3.3)遞歸地(recursive)把小于基準(zhǔn)值元素的子數(shù)列和大于基準(zhǔn)值元素的子數(shù)列再次進(jìn)行排序贫贝。
4.舉例:
(1)要排序的數(shù)組是:[15, 22, 35, 9, 16, 33, 15, 23, 68, 1, 33, 25, 14]。//相對來說蛉谜,快速排序數(shù)值越大速度越快 稚晚。 快速排序是所有排序里面最快的 class Program { static void Main(string[] args) { int[] arr = { 15, 22, 35, 9, 16, 33, 15, 23, 68, 1, 33, 25, 14 }; //待排序數(shù)組 //控制臺(tái)遍歷輸出 Console.WriteLine("排序前的數(shù)列:"); foreach (int item in arr) Console.Write(item + " "); QuickSort(arr, 0, arr.Length - 1); //調(diào)用快速排序函數(shù)。傳值(要排序數(shù)組型诚,基準(zhǔn)值位置蜈彼,數(shù)組長度) //控制臺(tái)遍歷輸出 Console.WriteLine(); Console.WriteLine("排序后的數(shù)列:"); foreach (int item in arr) Console.Write(item+" "); Console.ReadLine(); } private static void QuickSort(int[] arr, int begin, int end) { if (begin >= end) return; //兩個(gè)指針重合就返回,結(jié)束調(diào)用 int pivotIndex = QuickSort_Once(arr, begin, end); //會(huì)得到一個(gè)基準(zhǔn)值下標(biāo) QuickSort(arr, begin, pivotIndex - 1); //對基準(zhǔn)的左端進(jìn)行排序 遞歸 QuickSort(arr, pivotIndex + 1, end); //對基準(zhǔn)的右端進(jìn)行排序 遞歸 } private static int QuickSort_Once(int[] arr, int begin, int end) { int pivot = arr[begin]; //將首元素作為基準(zhǔn) int i = begin; int j = end; while (i < j) { while (arr[j] >= pivot && i < j) //從右到左俺驶,尋找第一個(gè)小于基準(zhǔn)pivot的元素 { j--; //指針向前移 } arr[i] = arr[j]; //執(zhí)行到此幸逆,j已指向從右端起第一個(gè)小于基準(zhǔn)pivot的元素,執(zhí)行替換 while (arr[i] <= pivot && i < j) //從左到右暮现,尋找首個(gè)大于基準(zhǔn)pivot的元素 { i++; //指針向后移 } arr[j] = arr[i]; //執(zhí)行到此,i已指向從左端起首個(gè)大于基準(zhǔn)pivot的元素还绘,執(zhí)行替換 } //退出while循環(huán),執(zhí)行至此,必定是 i= j的情況(最后兩個(gè)指針會(huì)碰頭) //i(或j)所指向的既是基準(zhǔn)位置栖袋,定位該趟的基準(zhǔn)并將該基準(zhǔn)位置返回 arr[i] = pivot; return i; }
}
5.輸出結(jié)果排序前的數(shù)列: 15 22 35 9 16 33 15 23 68 1 33 25 14 排序后的數(shù)列: 1 9 14 15 15 16 22 23 25 33 33 35 68
- 快速排序的時(shí)間主要耗費(fèi)在劃分操作上拍顷,對長度為k的區(qū)間進(jìn)行劃分,共需k-1次關(guān)鍵字的比較塘幅;
- 最壞情況是每次劃分選取的基準(zhǔn)都是當(dāng)前無序區(qū)中關(guān)鍵字最小(或最大)的記錄昔案,劃分的結(jié)果是基準(zhǔn)左邊的子區(qū)間為空(或右邊的子區(qū)間為空),而劃分所得的另一個(gè)非空的子區(qū)間中記錄數(shù)目电媳,僅僅比劃分前的無序區(qū)中記錄個(gè)數(shù)減少一個(gè)踏揣。時(shí)間復(fù)雜度為O(n*n);
- 在最好情況下匾乓,每次劃分所取的基準(zhǔn)都是當(dāng)前無序區(qū)的"中值"記錄捞稿,劃分的結(jié)果是基準(zhǔn)的左、右兩個(gè)無序子區(qū)間的長度大致相等∮榫郑總的關(guān)鍵字比較次數(shù):O(nlogn)彰亥;
- 盡管快速排序的最壞時(shí)間為O(n*n),但就平均性能而言衰齐,它是基于關(guān)鍵字比較的內(nèi)部排序算法中速度最快者任斋,快速排序亦因此而得名。它的平均時(shí)間復(fù)雜度為O(nlogn)耻涛。