当前位置:   article > 正文

归并排序详解(C++实现)_归并排序c++

归并排序c++

学习视频:acwing算法基础课

目录

归并排序步骤:

代码实现

部分调试演示


基本思想:分治

归并排序步骤:

1.确定分界点mid=(l+r)/2 : 数组将数组要排序的 l到r的部分分为 l到(l+r)/2 和 (l+r)/2+1到r 两组

2.递归排序left部分,right部分

3.归并:把两个有序的数组合为一个有序的数组

        实现方法:假设两个有序数组为a[ ],b[ ],用一个新数组temp[ ]来记录答案

                 此时数组a,b已经排好序,所以i,j指针指向的数为数组a,b中最小的数。比较a[i],b[j],选其中较小的值放入temp数组,若相等则可任选一个放入。这里假设a[i]较小,则将a[i]的值放入temp数组,i右移一位

                 再次比较a[i],b[j],将较小的值放入temp数组,并让此指针后移一位,循环比较,直到有一指针到终点

                 假设i指针先到达终点,跳出循环,再将b数组j指针所指及之后的部分放到temp数组里

 

                                            a[i]<b[j],所以a[i]放入temp,i指针后移一位

                                                 b[j]<a[i],b[j]放入temp,j指针后移一位

                                                  b[j]<a[i],b[j]放入temp,j指针后移一位

    b[j]=a[i],这里设相等时将a数组中的数放入temp数组,所以a[i]放入temp数组,i指针后移一位

 

                                                   b[j]<a[i],b[j]放入temp,j指针后移一位

      b[j]=a[i],a[i]放入temp数组(这里设相等时将a数组中的数放入temp数组),i指针后移一位

                                                    b[j]<a[i],b[j]放入temp,j指针后移一位

                                             a[i]<b[j],所以a[i]放入temp,i指针后移一位

     a[i]<b[j],所以a[i]放入temp,i指针后移一位,但是i指针已经指到a数组末尾无法后移,跳出循环

 此时a指针已经遍历完毕,应将b数组从j指针开始遍历,将j指针及之后的所有数放入temp数组;从j指针开始的所有数只有一个12,所以将12放入temp,最后temp为2  3  5  6  6  8  8  9  10  12

代码实现

  1. #include<iostream>
  2. using namespace std;
  3. const int N = 100005;//数组最大存储量
  4. int q[N], temp[N], n;//q为待排序数组 temp为暂时保存答案的数组 n为待输入数组个数
  5. //归并排序
  6. void merge_sort(int l, int r)//l和r为待排序区间的两端
  7. {
  8. if (l == r) return;//当l与r重合时返回(此时数组只有一个数字)
  9. int mid = (l + r) / 2;//求mid
  10. merge_sort(l, mid);//排序l到mid
  11. merge_sort(mid + 1, r);//排序mid+1到r
  12. int i = l, j = mid + 1, t = 0;
  13. while (i <= mid && j <= r)//将待排序区间分为两个区间l到mid和mid+1到r
  14. {
  15. //谁小就将谁放入temp
  16. if (q[i] < q[j]) temp[t++] = q[i++];
  17. else temp[t++] = q[j++];
  18. }
  19. //哪个数组没遍历完就遍历哪个数组
  20. while (i <= mid) temp[t++] = q[i++];
  21. while (j <= r) temp[t++] = q[j++];
  22. //将排完序的数组放回原数组
  23. for (int i = l, t = 0; i <= r; i++, t++)
  24. {
  25. q[i] = temp[t];
  26. }
  27. }
  28. int main()
  29. {
  30. cin >> n;
  31. for (int i = 0; i < n; i++)
  32. {
  33. cin >> q[i];
  34. }
  35. merge_sort(0, n - 1);
  36. for (int i = 0; i < n; i++)
  37. {
  38. cout << q[i] << " ";
  39. }
  40. return 0;
  41. }

部分调试演示

 输入n  及数组元素


 断点放在merge_sort()调用这一句,merge_sort函数调用,传入参数merge_sort(0,6)


 进入merge_sort函数(为了方便以下简称ms函数)并继续运行到ms函数再次调用之前

此时l=0,r=6,mid=3

 


 调用ms(0,3)并继续运行到ms函数再次调用之前

此时l=0,r=3,mid=1

 


 调用ms(0,1)并继续运行到ms函数再次调用之前

此时l=0,r=1,mid=0

 


调用ms(0,0) 此时l=0,r=0,l==r    所以返回

 


 

 调用ms(1,1) 此时l=1,r=1,l==r    所以返回

 


 继续向下运行,此时l=0,r=1,mid=0;令i=l=0,r=mid=1

将区间0到1分为了 区间left:下标0 和 区间right:下标1

进入while循环比大小


 q[i]:q[0]=6       q[j]:q[1]=8      q[i]<q[j]  所以temp[t]:temp[0]=6

 i++后i=1,i>mid  所以跳出while循环

此时区间right还没遍历

所以遍历区间right

temp[1]=q[1]=8

 跳出while循环

 


 通过for循环将temp数组的数放回原数组

放回原数组后函数结束 返回上一级调用

 


 调用ms(2,3) 

 

接下来就是重复的过程 就不一一列举啦

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号