• c++ 归并排序


    归并排序算法时间复杂度较为稳定,一般为nlogn,而快速排序受源数组排序影响较大,今天来学习归并排序。

    一.归并排序代码

    首先上代码:可以直接运行

    1. #include
    2. using namespace std;
    3. void insertsort(vector<int>&nums, int left,int mid, int right)
    4. {
    5. if (nums[mid] <= nums[mid + 1])
    6. return;
    7. for (int i = left+1; i <= right; ++i)
    8. {
    9. int idx = i;
    10. while (idx > left && nums[idx] < nums[idx - 1])
    11. {
    12. swap(nums[idx], nums[idx-1]);
    13. --idx;
    14. }
    15. }
    16. }
    17. vector<int>temp;
    18. void merge(vector<int>&nums,int left,int mid,int right)
    19. {
    20. if (nums[mid] <= nums[mid + 1])
    21. return;
    22. for (int i = left; i <= right; ++i)
    23. temp[i] = nums[i];
    24. int x = left, y = mid + 1;
    25. for (int i = left; i <= right; ++i)
    26. {
    27. if (y > right|| (y<=right&&x<=mid&&temp[x] <= temp[y]))
    28. {
    29. nums[i] = temp[x];
    30. ++x;
    31. }
    32. else if (x>mid||(x<=mid&&temp[x]>temp[y]))//条件可省略
    33. {
    34. nums[i] = temp[y];
    35. ++y;
    36. }
    37. }
    38. }
    39. void mergesort(vector<int>&nums,int left,int right)
    40. {
    41. if (left >=right) return;
    42. int mid = left + (right - left)/2;
    43. mergesort(nums, left, mid);
    44. mergesort(nums, mid + 1, right);
    45. if (mid - left + 1 <= 10)
    46. insertsort(nums, left, mid, right);
    47. else
    48. merge(nums, left, mid, right);
    49. }
    50. int main()
    51. {
    52. vector<int>nums = { 2,1,4,6,5,88,99,0,999};
    53. int n = nums.size();
    54. temp.resize(n);
    55. mergesort(nums,0,n-1);
    56. for (auto &num : nums)
    57. cout << num << endl;
    58. return 0;
    59. }

    二.代码详解

    1.主函数

    主函数较为简单,就是定义数组,然后调用mergesort函数,最后打印输出。

    值得注意的是在主函数中我们将一个temp数组定义了大小,这个数组是辅助数组,在详细的有序合并的操作中用得到,因为我们需要好多次的合并,每次合并后的数组都不一样。

    2.mergesort函数

    这个函数就是一个递归函数,不断地去分割,直到分割到最后只有一个元素时,它会退出分割操作,然后这个元素会和分割出的另一半元素进行合并操作,合并完成跳到上一级继续合并。

    3.merge合并函数

    在合并函数中,首先如果左右两个已经是有序的,则不需要合并,直接返回。

    然后我们将要合并的left到right之间的元素拷贝到temp辅助数组中,

    因为原来左右两边就是有序的,所以我们只关注左右两边的起始索引,将较小的那个放进nums[i]中,

    特别要注意的是元素过界问题,因为只是归并操作,索引并不会突破数组上限,从而造成结果不正确而很难发现出问题。

    如果说y右侧索引超出了限定right,我们将temp[x]赋值给nums[i],此时x不会出上限。

    或者说y没出索引,x也没出索引,那么当temp[x]temp[x]赋值给nums[i].

    其余情况均是temp[y]赋值给nums[i]。

    4.插入排序insertsort 

    当right-left特别小的时候,我们可以直接使用插入排序,想象一下我们只有两个元素[2,1],

    插入排序只需要swap两个值即可,而不需要赋值给赋值数组。

    插入排序的思想是前面的数组元素是有序的,那么我遍历到第idx个元素时,我要把它插入到前面的合适位置,特别地如果这个值比较大,那么它不用动,

    如果它比较小,那么让他和idx-1的数进行不断交换,直到遇到合适的位置。 

  • 相关阅读:
    WR | 水源水耐药基因稳定赋存的关键:以致病菌为“源”,群落构建主导菌为“汇”...
    算法通关村第六关|白银|二叉树的层次遍历【持续更新】
    测试Python读写xml配置文件(续)
    Android面试每日一题(4): 哪些情况下会导致oom问题?
    docker安装es
    three图形控制页面
    本地电脑搭建Plex私人影音云盘教程,内网穿透实现远程访问
    提示工程(Prompt Engineering)指南(入门篇)
    计算机毕业设计java基于springboot医院急诊挂号系统
    Vue精美简洁登录页
  • 原文地址:https://blog.csdn.net/xianzhetime/article/details/133076609