快速排序
通过一趟扫描将待排序的元素分割成独立的三个部分:
- 左区间中所有元素均不大于基准元素
- 第二个是基准元素
- 右区间中所有元素均不小于基准元素。
- 再按此方法对第一个序列和第三个序列分别进行排序。
- 整个排序过程可以递归进行。
- 其实,每一趟的本质都是将基准元素进行归位,比基准元素小的在左区间,比基准元素大的在右区间。最后,所有的元素全部都归位了,序列也就成为有序的序列了。
- 如果还是不清楚快速排序的思想,可以看看下面这个网站上的动画,可能会更加的形象:排序动画网站(含快排、插入、归并等多种排序的动画)
#include <iostream>
#include <algorithm>
using namespace std;
/**
* 交换i位置和j位置的元素
*/
void swap(int *a, int i, int j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
/**
* 快排函数
* @param a 要排序的数组
* @param left 区间的左端点
* @param right 区间的右端点
*/
void quick_sort(int *a, int left, int right) {
//此时只有一个元素,不需要进行排序,直接返回
if (left >= right) {
return;
}
//取基准元素为left位置的元素
int mid = left;
//记住区间的左右端点
int _left = left, _right = right;
//当左哨兵位置小于右哨兵位置,则继续进行区间划分
while (left < right) {
//右哨兵从右边向左进行移动,直到遇到比基准元素小的停止运动
while (a[right] >= a[mid] && right > left) {
right--;
}
//左哨兵从左向右进行移动,直到遇到比基准元素大的
while (a[left] <= a[mid] && left < right) {
left++;
}
//交换左右两哨兵的元素
if (left < right) {
swap(a, left, right);
}
}
//将基准元素交换到左右哨兵相遇的位置
swap(a, mid, left);
//再对左区间进行快排
quick_sort(a, _left, left - 1);
//再对右区间进行快排
quick_sort(a, right + 1, _right);
}
int main() {
int a[] = {2, 5, 4, 3, 1, 9, 8, 8, 6, 7};
cout << "排序前:";
for (int i = 0; i < sizeof(a) / sizeof(int); i++) {
cout << a[i] << " ";
}
cout << endl;
quick_sort(a, 0, sizeof(a) / sizeof(int) - 1);
cout << "排序后:";
for (int i = 0; i < sizeof(a) / sizeof(int); i++) {
cout << a[i] << " ";
}
cout << endl;
return 0;
}