C++排序算法练习(快速排序)

  在所有的技艺中,武功是最强调内功的,比如同样都学了辟邪剑谱,为什么岳不群要比林平之厉害?武功的招式固然重要,但没有深厚的内功,威力会大打折扣.那么,内功是怎么练出来的呢?冬练三九,夏练三伏,古人早有定论.而这些道理用在程序开发上也一样适用.

每日练习开始!(本篇所涉及的方法为自己所以写,但有参考网络前辈的文章,在此致敬!)
不正确的地方,欢迎拍砖!

#include <iostream>
using namespace std;
///*算法步骤
// * 1.从数列挑一个"基准"元素(pivot);
// * 2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。
// * 3.在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
// * 4.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
//*/
//方法一:
template <typename T>
void printArr(T*a,size_t sz,string type)
{
    cout<<type<<":";
    for(auto i=0;i<sz;++i)
        cout<<a[i]<<" ";
    cout<<endl;
}
template <typename T>
T paritition_1(T*a,int low,int high)
{
    T pivot=a[low]; //First, select the first element of the sequence as the base element
    while(low<high)
    {
        while(low<high&&a[high]>=pivot)
            high--;
        a[low]=a[high];
        while(low<high&&a[low]<=pivot)
            low++;
        a[high]=a[low];
    }
    a[low]=pivot;
    return low;
}
template <typename T>
void quick_st(T*a,int low,int high)
{
    if(low<high)
    {
        int pivot=paritition_1(a,low,high);
        quick_st(a,low,pivot-1);
        quick_st(a,pivot+1,high);
        printArr(a,high-low+1,"quick");
    }
}
//方法二:
template <typename T>
T partion_2(T*a,int low,int high)
{
    auto pivot= a[low];//最开始,将基准设定为序列的首元素;
    auto  j = low;//定义一个基准元素的游标;
    for (auto i = j+1; i <= high; ++i)//遍历除基准元素外的其它元素;
    {
        if (a[i] < pivot)
        {
            j++; //如果基准元素大于正在遍历的元素,将游标右移;
            if ( j < i) //j在什么情况下和i相等呢?其实,j在这里不可能大于i的,最多和i相等;
                swap(a[i],a[j]);//将基准一直往右移动
        }
    }
    swap(a[j],a[low]);
    return j;
}
int Rand(int low, int high)
{
    int size = high - low + 1;
    return  low + rand()%size;
}
template <typename T>
int partion_3(T*a,int left,int right)//首先进行分区操作
{
    swap(a[Rand(left,right)],a[left]);//随机选择区间的一个数,将其与首元素进行交换
    int pivot = a[left];//将首元素当作标杆
    int j = left;
    for (int i = left+1; i <= right; ++i)//首先忽略首元素
    {
        if (a[i] < pivot)
        {
            j++;
            if ( j != i)
            {
                swap(a[i],a[j]);//将标杆数一直往右移动,遇到比标杆数小的就交换到从头开始的位置上
            }
        }
    }
    swap(a[j],a[left]);//j位置的元素和首元素互换,即可保证标杆元素左边为小于等于,右边为大于等于
    return j;
}
template <typename T>
void quick_st_ex(T* a,int left,int right)
{
    if (left >= right)
        return;
    auto pivot= partion_2(a,left,right);
    quick_st_ex(a,left,pivot-1);
    quick_st_ex(a,pivot+1,right);

}
int main()
{
    int a[]{9,1,4,7,3,5,2,34,5,677};
    int high=sizeof (a)/sizeof (int)-1;
      quick_st(a,0,high);
    quick_st_ex(a,0,high);
    printArr(a,high+1,"quick");
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值