• 23-数据结构-内部排序-归并排序


    目录

    归并排序

    一、简介:

    二、思路

    三、代码


    归并排序

    一、简介:

            归并,也叫合并,合二为一嘛,归并排序实际上相当于二叉树递归,先左右拆分,最后给数组拆分为每个数据为独立个体,再执行合并操作。

    时间复杂度:O(nlog_2{n})-----口令:快(快速排序)以nlog_2{n}归(归并排序)队(堆排序)

    空间复杂度:O(n)因为需要临时数组几个数据,临时数组大小就是几个。口令--饿鬼(归并)炸鸡(基数排序)块

    稳定性:稳定,因为归并的时候,优先归并前面那个范围的,相对位置不贵发生改变,

    口令--稳稳的幸福,鸡(基数排序)毛(冒泡排序)插(直接插入和折半插入排序)龟(归并排序)壳

    排序趟数:对N个元素进行K路归并,排序排序趟数t等于t=log_k{N}向上取整。

    移动次数:N个元素,进行k路归并,移动元素个数为:N*log_k{N}

    二、思路

    归并排序主要分为两步:第一步,给数组左右拆分;第二步两两合并

    第一步,给数组左右拆分:

    1. 给数组传进两个标记,表示数组范围,分别为low和high
    2. 当low
    3. 然后进入递归,左边递归数组范围时low和mid右边递归范围时mid+1和high。
    4. 就这样层层递归,递归到最后,每个数据都成叶子结点了,再执行归并操作,但一个元素时肯定有序,所以返回倒数第二层,执行归并操作,依次往上返。
    5. 步骤如图所示,但是,原理是图中从最下层开始递归,然后递归到最后,都递归成叶子结点了,返回倒数第二层开始第一次归并操作,开始两两合并,选大小。

    第二步两两合并:

    1. 叶子结点时,归并操作没用,因为只有一个元素,肯定有序,因此往倒数第二层返回,执行倒数第二层的归并操作。
    2. 归并时,我们是传了三个坐标,low,mid和high。
    3. 先创建个临时数组,给原数组的数值复制进去,用来对比最大或最小值,
    4. 再定义一个实际坐标,指向实际数组中要存放的位置,
    5. 就这个要存放的位置,来个循环,每次循环的时候,进行low到mid这个范围和mid+1到high这个范围进行比对,然后二选一存放值。
    6. 如果最后两两没法对比了,再给剩下的都放进实际数组即可

    三、代码

    1. #include <stdio.h>
    2. #include <malloc.h>
    3. void PrintSort(int *a,int len)
    4. {
    5. int i=0;
    6. for(i=0;i<len;i++)
    7. {
    8. printf("%d ",a[i]);
    9. }
    10. printf("\n");
    11. }
    12. void Merge(int *a,int low,int mid,int high)
    13. {
    14. int *b=(int*)malloc((high+1)*sizeof(int));
    15. int i;
    16. for(i=low;i<=high;i++)
    17. {
    18. b[i]=a[i];//临时数组,存进去值,用来取值比较。
    19. }
    20. //k为a数组实际指向的箭头
    21. int k=low;
    22. //用p,q两个箭头分别指向b数组中两个紧挨着的有序数组,然后判断谁打谁小,随后给a[k]重新赋值
    23. int p,q;
    24. //两数组对比,然后选出一个,赋值到a中,随后k++,a数组换下一个坐标接着重复 步骤
    25. for(p=low,q=mid+1,k=low;p<=mid&&q<=high;k++)
    26. {
    27. //在临时数组b中进行对比选择,最后赋值到实际数组a中
    28. if(b[p]<=b[q])
    29. {
    30. a[k]=b[p];
    31. p++;
    32. }
    33. else
    34. {
    35. a[k]=b[q];
    36. q++;
    37. }
    38. }
    39. //如果对比完,还有一个数组没有对比完,接着往后赋值即可。
    40. while(p<=mid)
    41. {
    42. a[k]=b[p];
    43. k++;
    44. p++;
    45. }
    46. while(q<=high)
    47. {
    48. a[k]=b[q];
    49. k++;
    50. q++;
    51. }
    52. }
    53. void MergeSort(int *a,int low,int high)
    54. {
    55. //归并排序是个递归过程,先从整体表,慢慢拆分
    56. //拆分成每个数据是个整体时,再执行归并操作
    57. //两个合并成一个,依次往回返回
    58. if(low<high)
    59. {
    60. int mid =(low+high)/2;
    61. MergeSort(a,low,mid);
    62. MergeSort(a,mid+1,high);
    63. Merge(a,low,mid,high);
    64. }
    65. }
    66. int main()
    67. {
    68. int a[7]={49,38,65,97,76,13,27};
    69. MergeSort(a,0,6);
    70. PrintSort(a,7);
    71. return 0;
    72. }

  • 相关阅读:
    个人论文一:关于雾中单目自监督深度估计的研究
    mmdetection用mmclassification的backbone
    git stash详解
    Java时间处理---Java8中时区相关类库介绍
    数据化运营16 活跃(下): 如何通过用户分层进⾏沉默唤醒?
    分解质因数——AcWing 197. 阶乘分解
    零钱兑换00
    Conda 创建、激活、克隆、删除虚拟环境
    linux,write:xxx has messages disabled 与 Ubuntu多用户同时登录的问题 ubuntu 20.04
    计算机毕业设计之java+ssm土家风景文化管理平台-旅游景点攻略网站
  • 原文地址:https://blog.csdn.net/m0_59844149/article/details/133934759