【算法】归并排序

介绍

思路:将两个有序的数组归并到一个更大的有序数组中。
原理:按照一定规则,将数组不断分割到最小单位进行排序,然后将结果归并。直到合并回原本数组长度。
特性:需要使用额外的空间。
思想:分治思想(分割大问题为一个个小问题,通过解决所有的小问题从而解决大问题)
实现:自顶向下,自底向上
环境:适用数据量较大的数据

建议

接下来的算法会涉及递归,建议一边看示意图一边自己实现下流程,对照着学习会记忆更深刻。

后续代码源于书籍《算法》

实现

在这里插入图片描述

原地归并

无论哪种归并排序的实现,都需要进行数据对比并归并。而原地归并就是实现这个逻辑。
单纯直接使用原地并归并不能使数组有序排序,而是要按规则多次使用才能得到有序数组。

逻辑:分别有两个对象指向头和中间+1的位置。循环从头开始,头尾对比后赋值当前指向对象,按照规则其中一个指向向前移动。循环直到尾为结束。
记忆点:头尾对比后,赋值当前。

       void merge(int a[], int low, int mid, int height)
       {
              int index = low;
              int j = mid + 1;
              for (int k = low; k <= height; k++) {
                     aux[k] = a[k];
              }
              for (int k = low; k <= height; k++)
              {
                     if (index > mid)
                     {
                           a[k] = aux[j++];
                     }
                     else if(j > height)
                     {
                           a[k] = aux[index++];
                     }
                     else if (less(aux[j], aux[index]))
                     {
                           a[k] = aux[j++];
                     }
                     else
                     {
                           a[k] = aux[index++];
                     }
              }
       }

在这里插入图片描述

自顶向下

逻辑:递归将数组分为左右两个数组,从最小单位开始排序。排序后返回继续排序,直到回归整个数组。
记忆点:递归分组
解释:数组从大到小分组。从最小的数组开始有序,渐渐到大的数组有序。

       void sort(int* a, int low, int height)
       {
              if (height <= low)
              {
                     return;
              }
              int mid = low + (height - low) / 2;             
              sort(a, low, mid);
              sort(a, mid + 1, height);
              merge(a, low, mid, height);
       }

在这里插入图片描述

自底向上

逻辑:定义间隔值,将数组按间隔值分组,排序后,间隔值增加。直到间隔值为数组值。
记忆点:间隔分组
解释:数组从小到大分组。通过小部分有序,不断重新排序得到大的有序数组。

       void sort(int* a, int length)
       {
              for (int sz = 1; sz < length; sz = sz + sz)
              {
                     for (int low = 0; low < length - sz; low += sz + sz)
                     {
                           int mid = low + sz - 1;
                           int curLength = min(low + sz + sz - 1, length - 1);
                           merge(a, low, mid, curLength);
                     }
              }
       }

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值