快速排序
排序算法的主要思想:
1、从待排序的序列中任意选取一个元素作为基准(一般选择第1个元素作为基准),按照该元素的大小将整个序列分成两个子序列。
2、左子序列中的元素都小于基准,右侧子序列中的元素都大于基准,基准元素在两个子序列中间。
3、对上述两个子序列重复上面步骤1、步骤2,直到整个序列有序。
实例:
下面例子主要是当采用第1个元素作为基准,把整个序列分成两个子序列的过程。s使用pivotpos记录每次基准的位置,i记录当前循环的位置
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 基准 |
19 | 23 | 47 | 23 | 14 | 6 | 19 | |
pivotpos | i | i | i | i | |||
19 | 14 | 47 | 23 | 23 | 6 | 14、23互换 | |
pivotpos | i | i | |||||
19 | 14 | 6 | 23 | 23 | 47 | 6、47互换 | |
pivotpos | i | ||||||
6 | 14 | 19 | 23 | 23 | 47 | 6、19互换 |
快速排序的实现:
void quicksort(vector<int>& nums,int start,int end){
int pivotpos=partition(nums,start,end);
quicksort(nums,start,pivotpos-1);
quicksort(nums,pivotpos+1,end);
}
int partition(vector<int> ns,int left,int right){
int pivotpos=left,pivot=ns[left];
for(int i=left+1;i<=right;i++){
if(ns[i]<pivot){
pivotpos++;
int temp=ns[pivotpos];
ns[pivotpos]=ns[i];
ns[i]=temp;
}
}
ns[left]=ns[pivotpos];
ns[pivotpos]=pivot;
return pivotpos;
}
快速排序的性能分析:
- 快速排序是一种不稳定的算法,从上面的例子中可以看到序列中存在相同的元素23,但是在第一次交换时,两个23的相对顺序发生变化。
- 快速排序每次需要对一个元素进行定位,花费的时间是O(N)。并且每次划分之后把序列分成两个子序列,这是一个递归的过程。快速排序的平均计算时间是O(NlogN), 而且就平均时间而言快速排序是所有的排序算法中最好的一个。
- 由于快速排序是一个递归的过程,因此需要一个栈来存放每次调用时的指针和参数,因此需要的空间开销是O(logN)。
- 快速排序的运行时间和序列的规模有关,对于N比较大的情况,快速排序算法比较快,但是当N较小时,这种排序算法往往比其他的算法还要慢。
参考资料:
- 《数据结构(用面向对象方法与C++语言描述)》(第2版) 殷人昆 主编 清华大学出版社