程式設計之法第二章【快速排序的兩種方法】
阿新 • • 發佈:2019-02-17
花了兩個多小時重新複習了快速排序,之前以為懂,但是真正實踐的時候才發現自己錯了。
快速排序有兩種實現方式。都是兩個指標,不過之前學的一種是一個從頭開始掃,一個從尾開始掃。另外一種是兩個都是從頭開始掃,不過一個比另外一個前一個位置。
如果真正的理解快排的原理,對於一些排序的問題就會迎刃而解了。
例如奇偶分開,荷蘭國旗(相當於對012排序)
雖說今天花的時間比較多,但是理解了就感覺受益頗多,主要是思想,但是自己的實現能力還是不行。還是要多鍛鍊。
這是《程式設計之法》上的一道題目,將奇偶數分開,不考慮原始順序,我用兩種快排實現,可能還不是很正確,但是思路應該是對的。
#include <iostream> #include <algorithm> using namespace std; bool judge(int a) { return (a&1)==1; } //快排1 void OddEvenSort2(int *a,int l,int r) { int x=a[r]; int i=l-1,j=l; for(j=l; j<r; j++) { if(judge(a[j])) { i++; swap(a[i],a[j]); } } swap(a[r],a[i+1]); for(int i=0; i<=r; i++) cout<<a[i]<<" "; cout<<endl; } //快排2 void test(int *a,int l,int r){ int i=l,j=r,x=a[l]; while(i<j){ while(i<j&&!judge(a[j])) j--; if(i<j){ a[i]=a[j]; i++; } while(i<j&&judge(a[i])) i++; if(i<j){ a[j]=a[i]; j--; } } a[i]=x; for(int i=0; i<=r; i++) cout<<a[i]<<" "; cout<<endl; } int main() { int a[10]= {-121,15,241,-23,-121,57,15161,19,781,111}; test(a,0,9); OddEvenSort2(a,0,9); }
這是荷蘭國旗這道題,如果能夠理解快排的一種方法,那麼三種指標也容易理解了,難就難在分類討論要準確而已。
三種情況:(F:頭指標,C:當前指標,E:尾指標)
1.當C==0時,和F交換,C++,F++,因為0要放在前面。
2.當C==1時,不用換,C++
3.當C==2時,和E交換,E--,但是C不動,因為他有可能是0或者1,0的話還要和F交換,考慮一下(201012)應該就會明白了。
#include <iostream> #include <algorithm> using namespace std; void flag(int *a,int len) { int f=0,s=0,e=len-1; while(s<=e){ if(a[s]==0){ swap(a[s],a[f]); s++;f++; } else if(a[s]==1){ s++; } else{ swap(a[s],a[e]); e--; } } for(int i=0;i<len;i++) cout<<a[i]<<" "; cout<<endl; } int main(){ int a[10]={2,0,1,2,0,2,0,1,1,0}; flag(a,10); }