快速排序的三種實現方法
阿新 • • 發佈:2019-02-20
基本原理:
實現二:非遞迴演算法
實現三:三路劃分快速排序
通過一趟排序將待排元素分割成獨立的兩部分,其中一部分的元素都比另一部分小,則分別對這兩部分進行排序,最後達到整體有序。
實現一:遞迴演算法
void quicksort(int a[],int s,int t) { int low,high,tmp; low=s; high=t; if(low<high) { tmp=a[low]; while(low<high) { while(low<high&&a[high]>=tmp) high--; a[low]=a[high]; while(low<high&&a[low]<=tmp) low++; a[high]=a[low]; } a[low]=tmp; quicksort(a,s,low-1); quicksort(a,low+1,t); } }
實現二:非遞迴演算法
手動利用棧來儲存每次分塊快排的起始點和結束點,棧非空時迴圈獲取要排序的區間。
int partition(int a[],int s,int t) { int low,high,tmp; low=s; high=t; if(low<high) { tmp=a[low]; while(low<high) { while(low<high&&a[high]>=tmp) high--; a[low]=a[high]; while(low<high&&a[low]<=tmp) low++; a[high]=a[low]; } a[low]=tmp; } return low; } void quicksort1(int a[],int s,int t) { stack<int>m; int p=partition(a,s,t); if(p-1>s) { m.push(s); m.push(p-1); } if(p+1<t) { m.push(p+1); m.push(t); } while(!m.empty()) { int r=m.top(); //上界 m.pop(); int l=m.top(); //下界 m.pop(); p=partition(a,l,r); if(p-1>l) { m.push(l); m.push(p-1); } if(p+1<r) { m.push(p+1); m.push(r); } } }
實現三:三路劃分快速排序
二路劃分一次排序後結果陣列分為:小於等於元素的數,該元素,大於等於元素的數;
而三路劃分一次排序結束後結果陣列分為:小於元素的數,等於元素的數(一個或多個),大於元素的數。
具體實現:從首部開始遍歷時把遇到的與比較元素相同的數都移到最開始的位置;從尾部向前遍歷時把遇到相同的數都移到末尾位置;然後和首部相同的數和尾部相同的數都移到陣列中部來。遞迴遍歷首部的小數和尾部的大數。
void swap(int *a,int *b) { int tmp; tmp=*a; *a=*b; *b=tmp; } void quicksort2(int a[],int s,int t) { if(s<t) { int tmp=a[t]; int i=s-1,j=t; //記錄三次劃分後分割的位置s——i,i——j,j——t int p=s-1,q=t; //用來從前從後遍歷 while(1) { while(a[++i]<tmp){} //從前開始找到第一個大於等於x的元素 while(a[--j]>tmp) //從後開始找到第一個小於等於x的元素 { if(j==s) break; } if(i<j) { swap(a[i],a[j]); if(a[i]==tmp) //把相等的元素移到最開始 { p++; swap(a[p],a[i]); } if(a[j]==tmp) //把相等的元素移到最末尾 { q--; swap(a[q],a[j]); } } else break; } swap(a[i],a[t]); //設定第i位 j=i-1; //設定開始位置,j從i-1向前複製,i從i+1向後複製 i=i+1; for(int k=s;k<=p;k++,j--) swap(a[k],a[j]); for(k=t-1;k>=q;k--,i++) swap(a[i],a[k]); quicksort(a,s,j); quicksort(a,i,t); } }