- the worst-case running time is O(n^2);
- the expected running time is O(nlg n);
- it is an in place sorting algorithm.
- it is unstable;
main function
int main()
{
vector<int> vc;
srand((unsigned)time(NULL));
int temp = 0;
for(int i=0; i<COUNT; ++i){
temp = MIN + rand()%(MAX+MIN-1);
vc.push_back(temp);
}
vector<int>::iterator it;
for(it=vc.begin();it!=vc.end();++it){
cout << *it << " ";
}
cout << endl;
quickSort(vc, 0, vc.size()-1);
for(it=vc.begin();it!=vc.end();++it){
cout << *it << " ";
}
cout << endl;
return 0;
}
quickSort function
void quickSort(vector<int> &vc, int left, int right){
if(left < right){
int q = partition(vc, left, right); // return the index of the pivot element
quickSort(vc, left, q-1);
quickSort(vc, q+1, right);
}
}
对于主元(pivot element)的选择有三种方式
1.将每个数组或子数组的第一个元素作为主元
int partition(vector<int> &vc, int left, int right){
//position the first element of each queue as the pivot element
int key = vc[left];
int low = left;
int high = right;
while(low < high){
while(low<high && vc[high]>key)
--high;
if(low<high) // the if statement is important that cannot be omitted
vc[low++] = vc[high];
while(low<high && vc[low]<key)
++low;
if(low<high)
vc[high--] = vc[low];
}
vc[low] = key;
return low;
}
2.将每个数组或子数组的第一个、中间和最后元素的中间值最为主元,即三者取中
int partition(vector<int> &vc, int left, int right){
//position the intermediate value of the three element(head, tail and intermediate)
// as the pivot element
int mid_ele_index = midEleIndex(vc, left, (left+right)/2, right); // 取得中间元素的索引
int key = vc[mid_ele_index];
swap(vc[left], vc[mid_ele_index]); //在真正划分前进行一次交换
int low = left;
int high = right;
while(low < high){
while(low<high && vc[high]>key)
--high;
if(low<high) // the if statement is important that cannot be omitted
vc[low++] = vc[high];
while(low<high && vc[low]<key)
++low;
if(low<high)
vc[high--] = vc[low];
}
vc[low] = key;
return low;
}
int midEleIndex(vector<int> vc, int left, int mid, int right){
int a = vc[left], b=vc[mid], c=vc[right];
if((a>=b && a<=c) || (a<=b && a>=c))
return left;
else if((b>=a && b<=c) || (b<=a && b>=c))
return mid;
else
return right;
}
void swap(int &a, int &b){
int temp = a;
a = b;
b = temp;
}
3.随机选择一个元素作为主元
int partition(vector<int> &vc, int left, int right){
// 随机选择一个元素作为主元
srand((unsigned)time(NULL));
int rand_ele_index = left+rand()%(right-left+1);
int key = vc[rand_ele_index];
swap(vc[left], vc[rand_ele_index]);
int low = left;
int high = right;
while(low < high){
while(low<high && vc[high]>key)
--high;
if(low<high) // the if statement is important that cannot be omitted
vc[low++] = vc[high];
while(low<high && vc[low]<key)
++low;
if(low<high)
vc[high--] = vc[low];
}
vc[low] = key;
return low;
}
追加第四种方式
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 30
void exchange(int* a, int* b){
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int A[], int p, int r){ // 这种partition方法具有更高的效率,应该优先应用。
int x = A[r];
int i = p-1;
for(int j=p; j<r; ++j){
if(A[j] < x){
++i;
exchange(&A[i], &A[j]);
}
}
exchange(&A[i+1], &A[r]);
return i+1;
}
void quickSort(int A[], int p, int r){
int q;
if(p < r){
q = partition(A, p, r);
quickSort(A, p, q-1);
quickSort(A, q+1, r);
}
}
int main()
{
int A[N];
srand((unsigned)time(NULL));
for(int i=0; i<N; ++i){
A[i] = rand()%10000;
}
quickSort(A, 0, N-1);
for(int i=0; i<N; ++i){
printf("%d ", A[i]);
}
//printf("Hello world!\n");
return 0;
}
这种partition
方法是MIT算法导论中的方法,其相对严蔚敏版的partition
函数有更高的效率。因为相对后者,前者不需要做太多且容易出错的边界检查,只需要一个for
循环就可以对边界的情况加以限定,不会出现越界等错误。