数据结构值庖丁解牛八大算法排序,附动图和源码(快排-中B)

文章介绍了两种快速排序算法的实现方式:一是使用前后指针法的快速排序,通过调整指针找到合适位置并交换元素;二是采用非递归方法,利用栈来模拟递归过程,先处理左区间,再处理右区间,确保序列有序。这两种方法分别适用于不同场景,优化了排序效率。
摘要由CSDN通过智能技术生成

 c.前后指针法

这个方法的目的也是需要找keyi位置,定义两个指针prev,cur,cur++,prev++,直到找到比key所指向值大的cur停下,此时prev++,cur和prev所指向的值进行交换,直到cur走到空,把key所指向的值和prev的值进行交换。此时,找到了第一个keyi。再在快排中递归,直到所有数变得有序。实现代码如下:

int PartSort3(int * a, int begin, int end)
{
    int keyi = begin;
    int prev = begin, cur = begin+1;
    while(cur<=end)
    {

        //找到比key小的值的时候,跟++prev进行交换,小的往前翻,大的往后翻
        if(a[cur] <a[keyi] && ++prev != cur)
            Swap(&a[++prev],&a[cur]);


        ++cur;
    }
    
    //直到cur 走到空 prev和keyi的值进行交换
    Swap(&a[keyi],&a[cur]);
    
    keyi = prev;
    return keyi;
 }

void QucikSort(int * a, int begin , int end)
{
    if(begin >= end)
        return;
    if( (end- begin +1) >10)
        InsertSort(a+begin,end-begin+1);
    else
        {
            int keyi = PartSort3(a,begin,end);
            QuickSort(a,begin,keyi-1);
            QuickSort(a,keyi+1,end);
        }
}

 d.快排的非递归法,使用栈

具体的思想是:借助栈,实现先进后出的特点。假设有一个序列 6 1 2 7 9 3 4 5 10 8 ,begin指向6,end指向8,首先入栈begin和end ,先入begin,再入end,栈出的时候right就指向end,left指向begin,然后使用挖坑法去找到keyi,再去入栈左右子区间,我们想先处理左区间,再处理右区间,所以先入右区间,再入左区间,然后出栈,出栈的就是keyi-1(right),再出就是left,使用双指针法找到keyi,然后处理右区间,相同的方法,这里有一个小技巧,可以使用一个判断,判断keyi+1<right,表示的就是右区间里面至少还有2个数,没排完,继续排,left+1<keyi-1,表示左区间还没处理完。 直到遍历完所有区间,整个序列有序。实现代码如下:

void QuickSortR(int * a ,int begin, int end)
{
    //定义一个栈
    ST st;
    StackInit(&st);
    StackPush(&st,begin);
    StackPush(&st,end);
    //先排左边,再排右边 所以先入右边 再入左边
    
    while(!StackEmpty(&st))
    {
        int right = StackTop(&st);
        StackPop(&st);
        int left = StackTop(&st);
        StackPop(&st);
        
        int keyi = partSort3(a,begin,end);
        
        //[left,keyi-1],keyi,[keyi+1,right]
            //相当于递归中的返回值
           if(keyi +1 <right)
       //再去入栈 
         { 
            StackPush(&st,keyi+1);
            StackPush(&st,right);
         }
        if(left+1 <keyi)
        {
            StackPush(&st,left);
            StackPush(&st,keyi-1);
        }

     }
    StackDestroy(&st);
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值