快速排序一般是實際排序中應用最好的選擇,由於平均性能很好,且是原址排序,不穩定。ios
書上的大部份內容在分析其運行時間,感受看一下就行了(仍是蠻喜歡數學的,但是。。。)算法
#include <iostream> #include <algorithm> #include <random> using namespace std; //實際應用比較多,原址排序 typedef int index; index Partition(int *a, index p, index r){ int i = p - 1, j = p; for (; j < r; ++j){ //循環部分,嘗試循環不變式的思惟方式解題,證實 if (a[j] <= a[r]){ ++i; std::swap(a[i], a[j]);//若是使用^必須得判斷是否相等 } } std::swap(a[i + 1], a[r]); return i + 1; } //隨機版本的分割方式 index Random_Partition(int *a, index p, index r){ int rand_q = p+rand() % (r - p+1);//沒有使用引擎和分佈,感受好煩。 std::swap(a[rand_q], a[r]); return Partition(a, p, r); } //Hoare分割,算法導論7.1 index Hoare_Partition(int *a, index p, index r){ int temp = a[p]; int i = p - 1, j = r + 1; while (1){ do{ --j; } while (temp < a[j]); do{ ++i; } while (temp > a[i]); if (i < j) std::swap(a[i], a[j]); else return j; } } void HQuick_Sort(int *a, index p, index r){ if (p >= r) return; index q = Hoare_Partition(a, p, r); HQuick_Sort(a, p, q); HQuick_Sort(a, q+1, r); } void Quick_Sort(int *a,index p,index r){ if (p >= r) return; index q = Random_Partition(a, p, r); Quick_Sort(a, p, q-1); Quick_Sort(a, q+1, r); } //重複元素版快排算法導論7.2 pair<index, index> Partition_M(int *a, index p, index r){ int i = p - 1, j = p; int count = 0; for (; j < r; ++j){ if (a[j] <= a[r]){//想法與前面的快排差很少,過程就是記錄一下相同的值的個數, ++i; //若是相等的話就交換,不相等的話交換兩次。 if (a[j] == a[r]||count==0 ){ if (a[j] == a[r]) ++count; swap(a[i], a[j]); } else{ a[i - count] = a[j]; a[j] = a[i]; a[i] = a[r]; } } } swap(a[i+1], a[r]); return{ i + 1 - count, i + 1 }; } void Quick_Sort_M(int *a, index p, index r){ if (p >= r) return; pair<int,int> q = Partition_M(a, p, r); Quick_Sort(a, p, q.first-1); Quick_Sort(a, q.second+1, r); } //算法7.4 較淺棧深度的尾遞歸實現 void Re_Qsort(int *a, int p, int r){ while (p < r){ int q = Partition(a, p, r); if (q - p < r - q){ Re_Qsort(a, p, q - 1); p = q + 1; } else { Re_Qsort(a, q + 1, r); r = q - 1; } } } int main(){ int a[10] = { 3, 2, 4, 5, 1, 2, 4, 2, 9, 4 }; Re_Qsort(a, 0, 9); for (int i = 0; i < 10; ++i) std::cout << a[i]<<" "; int b[10] = { 3, 2, 4, 5, 1, 2, 4, 2, 4, 9 }; }