#include <iostream>
using namespace std;
//
// 交换 数组中两个元素
//
void swap(int *data, int a, int b)
{
int tmp = *(data + a);
*(data + a) = *(data + b);
*(data + b) = tmp;
}
//
// 对数组区间进行分割,返回支点位置
//
int partition(int *data, int begin, int end)
{
// 选择区间的第一个点作为 支点,暂存在变量pivot中
int pivot = *(data + begin);
// 接下来,扫描区间 从支点之后第一个元素到最后一个元素
int i = begin + 1;
int j = end;
while (true) {
// 从左向右扫描,如果元素值小于支点就向后移动
while (i <= j && *(data+i) < pivot) i++; // 注意:i <= j 而不是 i < j, 否则扫描区间不完整
// 从右向左扫描,如果元素值大于支点就向后移动
while (i <= j && *(data+j) >= pivot) j--; // 注意:i <= j 而不是 i < j, 否则扫描区间不完整
if (i > j) {
// 此时,扫描应该结束,i, j 位置是 j + 1 == i, j 在 i 前
break;
} else {
// 把 从左向右 找到的 大于支点的元素 和
// 从右向左 找到的 小于支点的元素 交换
swap(data, i, j);
}
}
// 扫描结束后,
// j 指向了 < pivot 区间最后一个元素 (区间元素个数是0时, 也成立),
// i 指向了 >= pivot 区间第一个元素 (区间元素个数是0时, 也成立),
// 因支点是取的是区间的第一个元素(位于 < pivot 区间一侧, 若支点取最后元素, 应取i作为分割点),
// 所以应该 把j 位置的值与pivot交换,j 也就是pivot点
swap(data, begin, j);
return j;
}
//
// 快速排序函数
//
void _q_sort(int *data, int begin, int end)
{
// 区间小于一个元素不需要分割
if (begin >= end) return;
// 分割成两个区间,p 是支点位置
int p = partition(data, begin, end);
// 递归调用 _q_sort 函数,分别对前后两个区间进行排序
_q_sort(data, begin, p - 1);
_q_sort(data, p + 1, end);
}
//
// 快速排序wrapper函数
//
void q_sort(int *data, int len)
{
_q_sort(data, 0, len - 1);
}
void print_array(int *data, int len)
{
for (int i = 0; i < len - 1; i++)
{
cout << data[i] << ", ";
}
cout << data[len - 1] << endl;
}
int main()
{
int data[] { 100, 2, 3, 1, 0, 10, 5, 4, 2, 3, 1, 0, 10, 5 };
// 排序前,数组
print_array(data, sizeof(data)/sizeof(data[0]));
// 调用快速排序算法
q_sort(data, sizeof(data)/sizeof(data[0]));
// 排序后,数组
print_array(data, sizeof(data)/sizeof(data[0]));
return 0;
}
快速排序(C++ 版)
最新推荐文章于 2024-01-25 02:00:00 发布