重溫快速排序(r4筆記第73天)
說起排序,總是會想起大名鼎鼎的快速排序,等自己再次翻開快速排序時,感覺是很陌生的,從這個對比也能看出自己確實是已經忘記了曾經重要的日子。 快速排序使用了分治思想,分而治之。為了達到它傳說中較低的時間度,接受了來自大家多年的挑戰還依然是名副其實的快速排序。 一個簡單的例子就是通過簡單的例項來說明。 我們假設一組數字如下: 6,9,4,1,8,7,2,3,5 我們假設以第一個數為參考,即temp為6,兩邊的數分別為i,j,從這組數的兩邊來比較這個中間變數,不斷的移動下標,從右邊開始尋找比temp小的數,從左邊開始和尋找比temp大的數。 在這個例子中就是以8為基本的參考,分別從這組數的右邊,左邊開始移動下標,尋找分別是小於6,大於6的節點。 需要經過這麼幾輪的比較。 第一輪,我們發現右邊第一個節點5<6,就是它了,從左邊開始,節點9>6,需要對這個兩個節點進行對調。 6,9,4,1,8,7,2,3,5 變為 6,5,4,1,8,7,2,3,9 繼續移動下標,從右邊開始尋找小於6的,從左邊開始尋找大於6的數,結果我們比較一番,發現數3<6,8>6 所以結果如下: 6,5,4,1,8,7,2,3,9 變為: 6,5,4,1,3,7,2,8,9 接下來繼續移動下標,發現,2<6,7>6得到的結果如下: 6,5,4,1,3,7,2,8,9 變為: 6,5,4,1,3,2,7,8,9 這個時候從右,從左下標都沒法再移動了,再移動就交叉了,這個時候就是需要對這組數進行劃分了,劃分的基本參考就是6 6,5,4,1,3,2,7,8,9 變為: 2,5,4,1,3,6,7,8,9 這個時候就分成了兩組數2,5,4,1,3 和7,8,9兩組數,然後根據分治思想需要對著兩組數進行進一步的比較。 右邊的3個數7,8,9已經是最後結果了,我們來看看左邊的數,2,5,4,1,3 設定temp=2,然後下標繼續從右,從左開始移動。 2,5,4,1,3 變為: 2,1,4,5,3 然後下標繼續移動就移動不了了。繼續拆分。 變為1,2, 4,5,3 繼續比較,拆分得到最後的結果。 通過程式的實現如下:
void quicksort(int left,int right) { int i,j,t,temp; if(left>right) return; temp=a[left]; //temp中就是基準數,取第一個數 i=left; j=right; while(i!=j) { //順序很重要,要先從右邊開始找 while(a[j]>=temp && i<j) j--; //再找左邊的 while(a[i]<=temp && i<j) i++; //交換兩個數在陣列中的位置 if(i<j) { t=a[i]; a[i]=a[j]; a[j]=t; } } //最後分拆,得到兩組數,對基準書進行重新初始化 a[left]=a[i]; a[i]=temp; quicksort(left,i-1);//處理左邊的 quicksort(i+1,right);//處理右邊的 }