两种常见的排序算法:快速排序和归并排序

1. 快速排序

1.1 算法思路

对于一个给定的数组,我们让数组其中一个元素为枢纽值,其他元素都与其进行比较,比枢纽值小

的放在左边,比枢纽值大的放在右边,这样的话,数组被分为两个部分,左半部分都是比枢纽值小

的,右半部分都是比枢纽值大的。而根据此思路一直递归,最后便可得到排序好的数组。

1.2 算法实现

//快速排序--分治
void quick_sort(int q[],int l,int r){
    if(l >= r)//判边界,l为左边界,r为右边界。
        return;
    int m = q[l],i = l - 1,j = r + 1;//定义两个指针,i为左指针,j为右指针,两指针分别向中间走,q[l]为比较的枢纽。
    while(i < j){//循环进行的条件:左指针小于右指针
        do i++;while (q[i] < m);//如果q[i]小于枢纽值,说明其位置符合条件,左指针向右移动。
            do j--;while(q[j] > m);//如果q[j]大于枢纽值,说明其位置也符合条件,右指针向左移动。
                if(i < j)//i < j说明遇到了不符合条件的情况,则直接交换两指针指向的元素,进入下一轮循环。
                    swap(q[i],q[j]);

    }
    quick_sort(q,l,j);//递归处理小于x的左半部分
    quick_sort(q,j + 1,r);//递归处理大于x的右半部分
}

说明:

l 和 r 为数组的左边界和右边界,因为每次递归处理,区间都相当于减半,需要重新规定排序的范围。

i 和 j 分别为数组的左指针和右指针(不是传统意义上的指针,可以理解为下标),他们的值分别

为数组左右边界的下标值,算法进行时,两指针分别向数组中间走,看所指向的值是否满足小于枢

纽值或是大于枢纽值的(左小,右大)。如果两指针遍历完发现 i 本身的值仍小于 j 本身的值,说

明 i 此时指向的值是大于枢纽值的,或是 j 指向的值是小于枢纽值的,不符合条件,则直接将两数

组值进行交换。至此递归体完成,再对左半部分和右半部分分别递归即可。

1.3.具体实例分析

给定数组:

5 2 7 6 8

执行流程

2. 归并排序

2.1 算法思路

对于两个已经排好序的数组,我们只需要每次将两个数组的左值依次比较,最后一个一个赋值到新

的数组里,新的数组即为排好序的数组。

也就是说将原数组分成的两个子数组按上述方法进行遍历,最后得到的新的数组即为排好序的数组。

这说明该算法要先对数组的左半部分和右半部分进行递归,最后再进行遍历赋值新数组。

2.2 算法实现

//归并排序:分治
void merge_sort(int q[],int l,int r){
    if(l >= r)//分别找到左边界和右边界
        return;
    int mid = (l + r) / 2;//找到中间值(数组中间)
    merge_sort(q, l ,mid);//递归排序中间值的左半边
    merge_sort(q, mid + 1, r);//递归排序中间值的右半边
    int k = 0,i = l, j = mid  + 1;//k用来记录每个数存到了temp数组的哪个下标,i是左半部分的左指针,j是右半部分的左指针,现在这两个子数组都是有序的,同时遍历两个子数组进行数组的重构
    while(i <= mid && j <= r){
        if(q[i] <= q[j])
            temp[k ++] = q[i ++];
        else
            temp[k ++] = q[j ++];

    }
    while(i <= mid)//如果左半部分的数组没有遍历完,则将未遍历完的数组加到temp数组的后面去
        temp[k++] = q[i++];
    while(j <= r)//如果右半部分的数组没有遍历完,则将未遍历完的数组加到temp数组的后面去
        temp[k++] = q[j++];
    for(i = l,j = 0;i <= r;i++,j++)//将结果数组复制到原数组里
        q[i] = temp[j];

}

思路与快速排序有些相似之处,只不过该算法是先递归,后进行排序操作,具体解读在注释里。

2.3 具体实例分析

给定数组

5 2 7 6 8

执行流程

3.总结

两种算法的本质是相同的,思想都是分治,即分而治之。将一个大数组分成多个小数组分别进行处

理。最后合起来得到的数组即为目标数组。

注意:两种排序算法不仅仅能用于排序,稍加修改便可以去解其他的题,如归并排序稍加修改就可

以去求一个序列中的逆序数。

所以,我们对算法的执行流程需要高度理解,不仅仅是背过代码就可以。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值