一、概念
快速排序是基于分治模式的
快排的运行时间与划分是否对称有关、
最坏情况下,时间复杂度是O(n^2),最好情况下,时间是O(nlgn)
二、程序
#include <iostream> using namespace std; //输出过程 void Print(int *A, int len) { for(int i = 0; i < len; i++) { if(i)cout<<' '; else cout<<"==> A = {"; cout<<A[i]; } cout<<'}'<<endl; } /************************普通快排************************************************/ //划分 int Partition(int *A, int p, int r) { //选择A[r]作为主元 int x = A[r]; int i = p - 1, j; for(j = p; j < r; j++) { //小于主元的放在左边 if(A[j] <= x) { i++; //把大于主元的交换到右边 swap(A[i],A[j]); } } swap(A[i+1], A[r]); //返回最终主元的位置 return i+1; } void QuickSort(int *A, int p, int r) { if(p < r) { //以某个主元为标准,把数组分为两部分,左边都比主元小,右边都比主元大 int q = Partition(A, p, r); //分别对左边和右边排序 QuickSort(A, p, q-1); QuickSort(A, q+1, r); } } /********************随机快排******************************************************/ //划分 int Randomized_Partition(int *A, int p , int r) { //随机选择一个数作为主元 int i = rand() % (r-p+1) + p; swap(A[r], A[i]); return Partition(A, p, r); } //排序,原理与普通快排相同,只是调用的划分方法不同 void Randomized_QuickSort(int *A, int p, int r) { if(p < r) { int q = Randomized_Partition(A, p, r); Randomized_QuickSort(A, p, q-1); Randomized_QuickSort(A, q+1, r); } } /********************Hoare快排***********************************************/ //划分 int Hoare_Partition(int *A, int p, int r) { int x = A[p], i = p - 1, j = r + 1; while(true) { do{j--;} //找到左边大于主元的数 while(A[j] > x); do{i++;} //找到右边小于主元的数 while(A[i] < x); //交换这两个数 if(i < j) swap(A[i], A[j]); //返回主元的位置 else return j; } } //排序,原理与普通快排相同,只是调用的划分方法不同 void Hoare_QuickSort(int *A, int p, int r) { if(p < r) { int q = Hoare_Partition(A, p, r); Hoare_QuickSort(A, p, q-1); Hoare_QuickSort(A, q+1, r); } } /********************Stooge快排*********************************************************/ void Stooge_Sort(int *A, int i, int j) { if(A[i] > A[j]) swap(A[i], A[j]); if(i + 1 >= j) return; k = (j - i + 1) / 3; Stooge_Sort(A, i, j-k); Stooge_Sort(A, i+k, j); Stooge_Sort(A, i, j-k); } /*************************尾递归快排************************************************/ void QuickSort2(int *A, int p, int r) { while(p < r) { int q = Partition(A, int p, r); //前面一半用递归 QuickSort2(A, p, q-1); //后面一半用迭代模拟递归 p = q + 1; } } //选择元素个数较小的一半递归,元素个数较多的一半用迭代模拟递归 void QuickSort3(int *A, int p, int r) { while(p < r) { int q = Partition(A, int p, r); if(r-q > q-p) { QuickSort3(A, p, q-1); p = q + 1; } else { QuickSort3(A, q+1, r); r = q - 1; } } } int main() { int A[12] = {13, 19, 9, 5, 12, 8, 7, 4, 11, 2, 6, 21}; Print(A, 12); Hoare_QuickSort(A, 0, 11); // Print(A, 12); return 0; }三、练习
7.1-1
A = {13 19 9 5 12 8 7 4 21 2 6 11} ==> A = {9 5 8 7 4 2 6 11 21 13 19 12} ==> A = {5 4 2 6 9 8 7 11 21 13 19 12} ==> A = {2 4 5 6 9 8 7 11 21 13 19 12} ==> A = {2 4 5 6 9 8 7 11 21 13 19 12} ==> A = {2 4 5 6 7 8 9 11 21 13 19 12} ==> A = {2 4 5 6 7 8 9 11 21 13 19 12} ==> A = {2 4 5 6 7 8 9 11 12 13 19 21} ==> A = {2 4 5 6 7 8 9 11 12 13 19 21} ==> A = {2 4 5 6 7 8 9 11 12 13 19 21}7.1-2
返回r
7.1-2
PARTITION(A, p, r)中的L4改为do if A[i] >= x
7.2-2
O(n^2)
7.2-4
基本有序的数列用快排效率较低
7.3-1
计算最坏情况,随机化就没有意义了
7.3-2
最好情况下,O(n)次
最坏情况下,O(lgn)次怎么算的?
7-1
a)
A = {13 19 9 5 12 8 7 4 11 2 6 21} ==> A = {6 19 9 5 12 8 7 4 11 2 13 21} ==> A = {6 2 9 5 12 8 7 4 11 19 13 21} ==> A = {4 2 9 5 12 8 7 6 11 19 13 21} ==> A = {4 2 5 9 12 8 7 6 11 19 13 21} ==> A = {2 4 5 9 12 8 7 6 11 19 13 21} ==> A = {2 4 5 6 12 8 7 9 11 19 13 21} ==> A = {2 4 5 6 7 8 12 9 11 19 13 21} ==> A = {2 4 5 6 7 8 9 12 11 19 13 21} ==> A = {2 4 5 6 7 8 9 12 11 13 19 21}e)
int Hoare_Partition(int *A, int p, int r) { int x = A[p], i = p - 1, j = r + 1; while(true) { do{j--;} while(A[j] > x); do{i++;} while(A[i] < x); if(i < j) swap(A[i], A[j]); else return j; Print(A, 12); } } void Hoare_QuickSort(int *A, int p, int r) { if(p < r) { int q = Hoare_Partition(A, p, r); Hoare_QuickSort(A, p, q-1); Hoare_QuickSort(A, q+1, r); } }7-3 void Stooge_Sort(int *A, int i, int j) { if(A[i] > A[j]) swap(A[i], A[j]); if(i + 1 >= j) return; k = (j - i + 1) / 3; Stooge_Sort(A, i, j-k); Stooge_Sort(A, i+k, j); Stooge_Sort(A, i, j-k); }
7-4
a)
void QuickSort2(int *A, int p, int r) { while(p < r) { int q = Partition(A, int p, r); QuickSort2(A, p, q-1); p = q + 1; } }b)
A = {1, 2, 3, 4, 5, 6}
c)
void QuickSort3(int *A, int p, int r) { while(p < r) { int q = Partition(A, int p, r); if(r-q > q-p) { QuickSort3(A, p, q-1); p = q + 1; } else { QuickSort3(A, q+1, r); r = q - 1; } } }7-6