快速排序(C++ 版)

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值