1. 程式人生 > 實用技巧 >快速排序實現(快排)

快速排序實現(快排)

/*
先來看下快排
9.9 快速排序
事實上,不論是C++ STL、java SDK或者.NETFrameWork SDK等開發工具包中的原始碼中都能找到它的某種實現版本。
快速排序演算法是由圖靈獎獲得者TonyHoare設計出來的,他在形式化方法理論以及AL-GOL60程式語言的發明中都有卓越貢獻,
是上世紀最偉大的電腦科學家之一,我們現在學習的這個快速排序演算法,被列為20世紀十大演算法之一。快去看下它到底有多牛吧。

希爾排序相當於直接插入排序的升級,他們同屬於插入排序類
堆排序相當於簡單選擇排序的升級,他們同屬於選擇排序類
而快速排序其實就是我們前面認為最慢的氣泡排序的升級,他們都屬於交換排序類,即他也是通過不斷比較和移動交換來實現排序的,
只不過它的實現,增大了記錄的比較和移動距離,將關鍵字較大的記錄從前面直接移動到後面,關鍵字較小的記錄從後面直接移動到前面,
從而減少了總的比較次數和移動交換次數。

快排思想:
    通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,
已到達整個序列有序的目的。
    從字面上感覺不出它的好處來。假設現在要對陣列{50,10,90,30,70,40,80,60,20}進行排序。我們通過程式碼的講解來學習快速排序的精妙。
*/ //對順序表L作快速排序 void QuickSort(SqList *L) { QSort(L, 1, L->length); } /* ---------尋找樞軸記錄,並在尋找的過程中swap交換排序-------是演算法的重點 交換順序表L中子表的記錄,使樞軸記錄到位,並返回其所在位置 此時在它之前(後)的記錄均不大(小)於它 */ int Partition(SqList *L, int low, int high) { int pivotkey; //有子表的第一個記錄作樞軸記錄 pivotkey = L->r[low]; //從表的兩端交替向中間掃描
while (low < high) { while(low < high && L->r[high] >= pivotkey) high--; //將比樞軸記錄小的記錄交換到低端 swap(L, low, high); while(low < high && L->r[low] <= pivotkey) low++; //將比樞軸記錄大的記錄交換到高階 swap(L, low, high); }
//返回樞軸記錄所在位置 return low; } //對順序表L中的子序列L->r[low..high]作快速排序 void QSort(SqList *L, int low,int high) //這裡的low和high { int pivot; if (low < high) { //將L->[low..high]一分為二 //算出樞軸值pivot pivot = Partition(L, low, high); //對低子表遞迴排序 QSort(L, low, pivot -1); //對高子表遞迴排序 QSort(L, pivot+1, high); } }