筆者近期在寫一個須要計算中位數的功能,而後須要調用數組的排序功能。因而筆者自帶的排序功能十分好奇,查了下發現自帶的排序其實是應用的快速排序,爲了能更好的理解快速排序以及認識其比較合適的使用場景,故手動實現並記錄下來:算法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { class Program { static int[] test = new int[] {6,1,4,3,5,8 }; /// <summary> /// 一遍 快速排序 /// </summary> /// <param name="a">待排數組</param> /// <param name="low">排序起始值</param> /// <param name="high">排序最高值</param> /// <returns>中樞值位置</returns> public static int Partition(ref int[] a,int low,int high) { // 設置中樞值 int pivotkey = a[low]; // 確保不進入死循環,當low指針大於high叫停 while (low < high) { // 若是high哨兵的值小於中樞值,則將high的值與中樞值調換(中樞值保存了副本pivotkey!) while (low < high && a[high] >= pivotkey) high--; a[low] += a[high]; a[high] = a[low] - a[high]; a[low] -= a[high]; // 若是low哨兵的值大於中樞值,則將low與中樞值調換 while (low < high && a[low] <= pivotkey) low++; a[low] += a[high]; a[high] = a[low] - a[high]; a[low] -= a[high]; } // 結束比對,low和high會碰在一塊兒,此時將中樞值副本值插入low的位置 a[low] = pivotkey; return low; } /// <summary> /// 快速排序 /// </summary> /// <param name="a">待排數組</param> /// <param name="low">排序起始值</param> /// <param name="high">排序最高值</param> public static void QuickSort(ref int[] a, int low, int high) { // 加入這個low<high ,一個是確保數組的長度大於1,二是肯定遞歸結束的條件,防止進入死循環,棧溢出 if (low < high) { // 每次獲取中樞值的位置 int pivotloc = Partition(ref a, low, high); // 利用中樞值將每遍排好序的數組分割成兩份,接着從low到pivotkey-1 以及 pivotkey+1 到 high兩個區域進行排序 // 這裏加入比較兩端的長度,旨在下降棧的最大深度(下降至logn) if ((pivotloc - low) <= (high - pivotloc)) { QuickSort(ref a, low, pivotloc - 1); QuickSort(ref a, pivotloc + 1, high); } else { QuickSort(ref a, pivotloc + 1, high); QuickSort(ref a, low, pivotloc - 1); } } } static void Main(string[] args) { QuickSort(ref test,0,test.Length-1); foreach (var item in test) { Console.Write(item + " "); } Console.ReadKey(); } } }
資料上顯示,快速排序就平均時間而言是目前被認爲最好的一種內部排序算法!數組