上一篇我们用了三种方法实现了基础快排,但是也有一些问题要去进行改进
这里我们要对快排算法进行分析
我们分别都来画图示意一下
第一趟进行n-1次比较,第二趟n-2 … (n-1)+(n-2)+…+1=n2/2
所以快排的效率就是O(logN)
如果是像这样的情况,第一次选key时,我们就要注意,不要选到9,所以我们写了一个函数,三数取中,避免我们选到当前待排序列的最大或最小
//三数取中(优化快排的最坏情况) int GetMidIndex(int*a, int left, int right) { int mid = left + ((right - left) >> 1); //left mid right //三个数比大小,取中数,这样就可以避免掉最坏的情况 if (a[left] < a[mid]) { if (a[mid] < a[right]) { return mid; } else if (a[left]<a[right]) { return right; } else { return left; } } else //left>mid { if (a[mid] > a[right]) { return mid; } else if (a[left]>a[right]) { return right; } else { return left; } } }对于小区间用插入排序
//对于递归版的再优化,少用栈帧 void QuickSortBetter(int*a, int left, int right) { //a不能为空 assert(a); //a不能只有一个数 if (left >= right) return; //小区间进行优化,不用递归更快 if (right - left < 10) { //小区间用插入排序 InsertSort(a + left, right - left + 1); } else { int div = _PartSort2(a, left, right); //再排剩下的左边的和右边的区域 QuickSortBetter(a, left, div - 1); QuickSortBetter(a, div + 1, right); } }