【算法基础】快速排序和归并排序

快速排序

void quick_sort(int q[],int l,int r)
{
    if(l>=r) return;//递归终止
    
    int st=l-1,ed=r+1;
    int x=a[l+r+1>>1];
    
    while(st<ed)
    {
        do st++;while(a[st]<x);
        do ed--;while(a[ed]>x);
        
        if(st<ed)swap(a[st],a[ed]);
    }
    
    quick_sort(q,l,st-1);
    quick_sort(q,st,r);
}

算法思想:

本质是分治,先找一个值x让数组左边的一部分小于x,右边的一部分大于x,如此递归下去即可

详述:

中间值的选取:不能选取左右端点,因为如果所给的数组本身就是排好序的那么就会调用n次函数,时间复杂度会降低到O(n^2),只能选取l+r>>1或者l+r+1>>1;

为什么采用do while:因为使用while循环即:

while(q[i]<x)i++;
while(q[j]>x)j--;

当q[i]和q[j]都为x时,i和j不会更新,导致外层的while循环陷入死循环;

为什么do while中的循环条件中没有等于:如果数组中有很多和x相等的数,那么在循环中就会跳过这个数,而忽略了另一边可能有需求的数。此处可以让相等的数停止循环于另一端需要交换的进行交换。总之就是让循环在恰当的位置停止。

算法中的循环(结束后)会让st左边的值(不包括st自己)都是小于等于x,会让ed右边的值(不包括ed自己)都是大于等于x;所以如果x取的是l+r+1,那么递归就需要使用st-1和st;如果x取的是l+r,那么递归就需要使用ed和ed+1

归并排序

void merge_sort(int q[],int l,int r)
{
    if(l>=r)return;
    
    int mid=l+r>>1;
    merge_sort(q,l,mid);
    merge_sort(q,mid+1,r);
    
    int k=l;
    int i=l,j=mid+1;
    while(i<=mid&&j<=r)
    {
        if(q[i]>q[j])tmp[k++]=q[j++];
        else tmp[k++]=q[i++];
    }
    while(i<=mid)tmp[k++]=q[i++];
    while(j<=r)tmp[k++]=q[j++];
    
    for(int p=l;p<=r;p++)
    q[p]=tmp[p];
}

同样是分治,比较容易理解,就不需要多讲了。

分治思想

第一步:分成子问题

第二步:递归处理子问题

第三步:合并子问题

经典题目:

快速排序

归并排序

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值