快速排序C++

快速排序讲解C++

快速排序利用了分治的思想,分而治之。通过一趟排序将序列分为两部分,其中一部分比较关键字小,一部分比关键字大。之后继续对这两个子序列重复此过程,直到整个序列都有序。

主要思路

选基准值:在要排序的序列中选一个几个基准值,作为划分区间的 关键字。
分割序列:按照基准值把序列分为两部分,左边的小于基准值,右边的大于基准值。
重复分割:对子序列重复上面的步骤,直到序列为空或者只有一个元素。当递归处理的所有子序列都返回时,序列有序。

代码演示

// 版本一 填充法  初始的时候默认最后一个数字是基准值 最后一个数挖坑
//从左向右开始进行,当当前值小于基准值并且i<j,则i++; 否则将当前值挖出,并填到之前的坑(第一次是最后一个值),将j值前移
//接下来开始从右向左进行,当当前值大于基准值并且i<j, 则j--; 否则将当前值挖出,并填到之前的坑(上一次是s[i]),将i值后移
//循环的结束条件是 i>=j ,执行条件是i<j 
int partition1(vector<int> &v, int left, int right)
{
    if (left < right)
    {
        int i, j;
        int flag;
        i = left;
        j = right-1;
        flag = v[j];

        while (i<j)
        {
            while (v[i]<flag&&i<j)
            {
                i++;
            }

            if (i < j)
            {
                v[j--] = v[i];
            }

            while (v[i]>flag&&i<j)
            {
                j--;
            }

            if (i < j)
            {
                v[i++] = v[j];
            }
        }
        v[j] = flag;
        return j;
    }

}

void QuickSort1(vector<int>& v, int left, int right)
{
    if (left < right)
    {
        int boundary = partition1(v, left, right);
        QuickSort1(v, left, boundary);
        QuickSort1(v, boundary + 1, right);
    }
}
//交换版本  交换法   初始的时候默认最后一个数字是基准值 
//从左向右开始进行,当当前值小于   等于   基准值并且i<j,则i++;   循环跳出当前值 是一个大于基准的值 i指向
//接下来开始从右向左进行,当当前值大于   等于   基准值并且i<j, 则j--;  循环跳出当前值 是一个小于基准的值 j指向
//将上边找到的两个数字交换
//循环的结束条件是 i>=j ,执行条件是i<j   
//最后进行判断 当前的结束值 是否是最后一个数字(即保存的基准值)  如果不是二者进行交换。
int partition2(vector<int> &v, int left, int right)
{
    if (left < right)
    {
        int i, j;
        int flag;
        i = left;
        j = right - 1;

        flag = v[right-1];
        while (i<j)
        {
            while (v[i]<=flag&&i<j)
            {
                i++;
            }

            while (v[j]>=flag&&i<j)
            {
                j--;
            }

            if (i < j)
                swap(v[i],v[j]);
        }

        if (j != right - 1)
        {
            swap(v[j], v[right - 1]);
        }
        return j;
    }
}

void QuickSort2(vector<int>& v, int left, int right)
{
    if (left < right)
    {
        int boundary = partition2(v, left, right);
        QuickSort2(v, left, boundary);
        QuickSort2(v, boundary + 1, right);
    }
}
//非递归版本 使用栈结构来保存每次的开始和结束位置
void QuickSort4(vector<int> &v, int left, int right)
{
    if (left >= right)
        return;
    stack<int> s;

    s.push(left);
    s.push(right);

    while (!s.empty())
    {
        int i, j;
        j = s.top();
        s.pop();
        i = s.top;
        s.pop();

        if (i < j)
        {
            int flag = partition2(v,i,j);

            //左区间
            s.push(i);
            s.push(flag);

            //右区间
            s.push(flag+1);
            s.push(j);
        }

    }
}

完整代码

链接: https://pan.baidu.com/s/1pL5hrOf 密码: 3ez1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值