• 数据结构与算法基础-学习-33-归并排序


    目录

    一、基本思想

    二、算法思路

    1、合并两个有序序列

    2、分治法

    三、算法源码

    1、MergeSortTwoSortData

    2、TwoWayMergeSortRecurtionSentryQueue

    四、算法效率分析

    五、Linux环境编译测试

    六、小感慨


    排序的其他相关知识点和源码分享可以参考之前的博客:   

    数据结构与算法基础-学习-30-插入排序之直接插入排序、二分插入排序、希尔排序》,

    数据结构与算法基础-学习-31-交换排序之冒泡排序、快速排序》,

    数据结构与算法基础-学习-32-选择排序之简单选择排序、堆排序

    一、基本思想

    将两个或两个以上的有序子序列“归并”为一个有序序列。

    在内部排序中,通常采用的是2路归并排序。

    也就是将两个位置相邻的有序子序列R[l..m]和R[m+1..n]归并为一个有序序列R[l..n]。

    二、算法思路

    归并排序分两个部分进行实现,第一个部分就是将两个有序的序列合并成一个有序的序列。第二部分利用递归的思想将序列拆分成多个元素进行排序。

    1、合并两个有序序列

    (1)两个有序序列我们放在了一个数组中进行合并。Low和Mid分别表示Pre的起始和结束节点。Mid+1和High分别表示Tail的起始和结束节点。我们这里还是以升序为例,Pre的6和Tail的4进行比较4小,4插入到新的数组中。

    (2)Tail前进一,Pre的6和Tail的5进行比较5小,5插入到新的数组中。

    (3)Tail前进一,Pre的6和Tail的8进行比较6小,6插入到新的数组中。

    (4)Pre前进一,Pre的9和Tail的8进行比较8小,8插入到新的数组中。

    (5)Tail前进一,Tail已经超过High了,说明后半段有序序列已经访问完毕,这时只需把前半段的Pre开始遍历插入到新数组即可。

    2、分治法

    分治法其实就是把一个任务拆成多个小的任务,小的任务都完成了就把整个大任务完成了,是一种思想,上面是给的一个序列前后正好包含两组有序的数组,如果换成是无序数组呢,我们只需要把无需数组分成两半,左边使其有序,右边使其有序,在进行合并即可,左边可以再分为两块,有一种套娃的感觉,这个时候我们是不是会联想到递归,其实递归的练习做多了,就会有这种想法冒出来,希望对大家有帮助。

    三、算法源码

    1、MergeSortTwoSortData

    1. //将队列中两个有序的序列进行合并。
    2. //例如Low到Mid升序排列,Mid加一到High升序排列。合并为一个升序队列。
    3. Status MergeSortTwoSortData(SqQueue* Queue,QueueLenType Low,QueueLenType Mid,QueueLenType High)
    4. {
    5. JudgeAllNullPointer(Queue);
    6. if (Queue->Flag != INT_TYPE_FLAG)
    7. {
    8. return FailFlag;
    9. }
    10. QueueLenType Pre = Low;
    11. QueueLenType Tail = Mid + 1;
    12. int* Array = (int*)(Queue->Data);
    13. SqQueue* TmpQueue = NULL;
    14. QueueLenType i;
    15. InitSqQueue(&TmpQueue, High - Low + 1, INT_TYPE_FLAG);
    16. while (Pre <= Mid && Tail <= High)
    17. {
    18. if (Array[Pre] > Array[Tail])
    19. {
    20. EnterSqQueue(TmpQueue,&(Array[Tail]));
    21. Tail++;
    22. }
    23. else if (Array[Pre] < Array[Tail])
    24. {
    25. EnterSqQueue(TmpQueue,&(Array[Pre]));
    26. Pre++;
    27. }
    28. else//等于
    29. {
    30. EnterSqQueue(TmpQueue,&(Array[Tail]));
    31. EnterSqQueue(TmpQueue,&(Array[Pre]));
    32. Tail++;
    33. Pre++;
    34. }
    35. }
    36. while (Pre <= Mid)
    37. {
    38. EnterSqQueue(TmpQueue,&(Array[Pre]));
    39. Pre++;
    40. }
    41. while (Tail <= High)
    42. {
    43. EnterSqQueue(TmpQueue,&(Array[Tail]));
    44. Tail++;
    45. }
    46. for (i = Low; i <= High; i++)
    47. {
    48. LeaveSqQueue(TmpQueue,&(Array[0]));
    49. Array[i] = Array[0];
    50. }
    51. DestroySqQueue(&TmpQueue);
    52. LogFormat(Debug,"Merge Sort Two Sort Data OK.\n");
    53. return SuccessFlag;
    54. }

    2、TwoWayMergeSortRecurtionSentryQueue

    1. void TwoWayMergeSortRecurtionSentryQueue(SqQueue* Queue,QueueLenType Low,QueueLenType High)
    2. {
    3. JudgeAllNullPointer(Queue);
    4. if (Low == High)
    5. {
    6. return;
    7. }
    8. else
    9. {
    10. QueueLenType Mid = (Low + High) / 2;
    11. TwoWayMergeSortRecurtionSentryQueue(Queue,Low,Mid);
    12. TwoWayMergeSortRecurtionSentryQueue(Queue,Mid + 1,High);
    13. MergeSortTwoSortData(Queue,Low,Mid,High);
    14. }
    15. }

    四、算法效率分析

    情况时间复杂度是否稳定
    最好O(n * log2^n)稳定
    最坏O(n * log2^n)
    平均O(n * log2^n)

    五、Linux环境编译测试

    1. [gbase@czg2 Sort]$ make
    2. gcc -Wall -Wextra -O3 InsertSort.c SwapSort.c SelectSort.c MergeSort.c BucketSort.c main.c -o TestSort -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/Log/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/HashTable/include/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/SqQueue/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/SqStack/ -L /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Make/Libs/ -lPublicFunction -lLog -lSqQueue
    3. [gbase@czg2 Sort]$ ./TestSort
    4. 2023-9-11--[ Debug ]--Init SqQueue OK
    5. 2023-9-11--[ Debug ]--Enter SqQueue OK
    6. 2023-9-11--[ Debug ]--Enter SqQueue OK
    7. 2023-9-11--[ Debug ]--Enter SqQueue OK
    8. 2023-9-11--[ Debug ]--Enter SqQueue OK
    9. 2023-9-11--[ Debug ]--Enter SqQueue OK
    10. 2023-9-11--[ Debug ]--Enter SqQueue OK
    11. 2023-9-11--[ Debug ]--Enter SqQueue OK
    12. 2023-9-11--[ Debug ]--Enter SqQueue OK
    13. 2023-9-11--[ Debug ]--Enter SqQueue OK
    14. 2023-9-11--[ Debug ]--Enter SqQueue OK
    15. 2023-9-11--[ Debug ]--Enter SqQueue OK
    16. 2023-9-11--[ Info ]--SqQueue Data :
    17. Data : [ 0 ,5 ,6 ,7 ,8 ,9 ,0 ,1 ,2 ,3 ,4 ]
    18. FrontIndex : 0
    19. RearIndex : 0
    20. SqQueueLen : 11
    21. SqQueueMaxLen : 11
    22. Flag : INT_TYPE_FLAG
    23. 2023-9-11--[ Debug ]--Init SqQueue OK
    24. 2023-9-11--[ Debug ]--Enter SqQueue OK
    25. 2023-9-11--[ Debug ]--Enter SqQueue OK
    26. 2023-9-11--[ Debug ]--Leave SqQueue OK
    27. 2023-9-11--[ Debug ]--Leave SqQueue OK
    28. 2023-9-11--[ Debug ]--Destroy SqQueue OK
    29. 2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
    30. 2023-9-11--[ Debug ]--Init SqQueue OK
    31. 2023-9-11--[ Debug ]--Enter SqQueue OK
    32. 2023-9-11--[ Debug ]--Enter SqQueue OK
    33. 2023-9-11--[ Debug ]--Enter SqQueue OK
    34. 2023-9-11--[ Debug ]--Leave SqQueue OK
    35. 2023-9-11--[ Debug ]--Leave SqQueue OK
    36. 2023-9-11--[ Debug ]--Leave SqQueue OK
    37. 2023-9-11--[ Debug ]--Destroy SqQueue OK
    38. 2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
    39. 2023-9-11--[ Debug ]--Init SqQueue OK
    40. 2023-9-11--[ Debug ]--Enter SqQueue OK
    41. 2023-9-11--[ Debug ]--Enter SqQueue OK
    42. 2023-9-11--[ Debug ]--Leave SqQueue OK
    43. 2023-9-11--[ Debug ]--Leave SqQueue OK
    44. 2023-9-11--[ Debug ]--Destroy SqQueue OK
    45. 2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
    46. 2023-9-11--[ Debug ]--Init SqQueue OK
    47. 2023-9-11--[ Debug ]--Enter SqQueue OK
    48. 2023-9-11--[ Debug ]--Enter SqQueue OK
    49. 2023-9-11--[ Debug ]--Enter SqQueue OK
    50. 2023-9-11--[ Debug ]--Enter SqQueue OK
    51. 2023-9-11--[ Debug ]--Enter SqQueue OK
    52. 2023-9-11--[ Debug ]--Leave SqQueue OK
    53. 2023-9-11--[ Debug ]--Leave SqQueue OK
    54. 2023-9-11--[ Debug ]--Leave SqQueue OK
    55. 2023-9-11--[ Debug ]--Leave SqQueue OK
    56. 2023-9-11--[ Debug ]--Leave SqQueue OK
    57. 2023-9-11--[ Debug ]--Destroy SqQueue OK
    58. 2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
    59. 2023-9-11--[ Debug ]--Init SqQueue OK
    60. 2023-9-11--[ Debug ]--Enter SqQueue OK
    61. 2023-9-11--[ Debug ]--Enter SqQueue OK
    62. 2023-9-11--[ Debug ]--Leave SqQueue OK
    63. 2023-9-11--[ Debug ]--Leave SqQueue OK
    64. 2023-9-11--[ Debug ]--Destroy SqQueue OK
    65. 2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
    66. 2023-9-11--[ Debug ]--Init SqQueue OK
    67. 2023-9-11--[ Debug ]--Enter SqQueue OK
    68. 2023-9-11--[ Debug ]--Enter SqQueue OK
    69. 2023-9-11--[ Debug ]--Enter SqQueue OK
    70. 2023-9-11--[ Debug ]--Leave SqQueue OK
    71. 2023-9-11--[ Debug ]--Leave SqQueue OK
    72. 2023-9-11--[ Debug ]--Leave SqQueue OK
    73. 2023-9-11--[ Debug ]--Destroy SqQueue OK
    74. 2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
    75. 2023-9-11--[ Debug ]--Init SqQueue OK
    76. 2023-9-11--[ Debug ]--Enter SqQueue OK
    77. 2023-9-11--[ Debug ]--Enter SqQueue OK
    78. 2023-9-11--[ Debug ]--Leave SqQueue OK
    79. 2023-9-11--[ Debug ]--Leave SqQueue OK
    80. 2023-9-11--[ Debug ]--Destroy SqQueue OK
    81. 2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
    82. 2023-9-11--[ Debug ]--Init SqQueue OK
    83. 2023-9-11--[ Debug ]--Enter SqQueue OK
    84. 2023-9-11--[ Debug ]--Enter SqQueue OK
    85. 2023-9-11--[ Debug ]--Enter SqQueue OK
    86. 2023-9-11--[ Debug ]--Enter SqQueue OK
    87. 2023-9-11--[ Debug ]--Enter SqQueue OK
    88. 2023-9-11--[ Debug ]--Leave SqQueue OK
    89. 2023-9-11--[ Debug ]--Leave SqQueue OK
    90. 2023-9-11--[ Debug ]--Leave SqQueue OK
    91. 2023-9-11--[ Debug ]--Leave SqQueue OK
    92. 2023-9-11--[ Debug ]--Leave SqQueue OK
    93. 2023-9-11--[ Debug ]--Destroy SqQueue OK
    94. 2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
    95. 2023-9-11--[ Debug ]--Init SqQueue OK
    96. 2023-9-11--[ Debug ]--Enter SqQueue OK
    97. 2023-9-11--[ Debug ]--Enter SqQueue OK
    98. 2023-9-11--[ Debug ]--Enter SqQueue OK
    99. 2023-9-11--[ Debug ]--Enter SqQueue OK
    100. 2023-9-11--[ Debug ]--Enter SqQueue OK
    101. 2023-9-11--[ Debug ]--Enter SqQueue OK
    102. 2023-9-11--[ Debug ]--Enter SqQueue OK
    103. 2023-9-11--[ Debug ]--Enter SqQueue OK
    104. 2023-9-11--[ Debug ]--Enter SqQueue OK
    105. 2023-9-11--[ Debug ]--Enter SqQueue OK
    106. 2023-9-11--[ Debug ]--Leave SqQueue OK
    107. 2023-9-11--[ Debug ]--Leave SqQueue OK
    108. 2023-9-11--[ Debug ]--Leave SqQueue OK
    109. 2023-9-11--[ Debug ]--Leave SqQueue OK
    110. 2023-9-11--[ Debug ]--Leave SqQueue OK
    111. 2023-9-11--[ Debug ]--Leave SqQueue OK
    112. 2023-9-11--[ Debug ]--Leave SqQueue OK
    113. 2023-9-11--[ Debug ]--Leave SqQueue OK
    114. 2023-9-11--[ Debug ]--Leave SqQueue OK
    115. 2023-9-11--[ Debug ]--Leave SqQueue OK
    116. 2023-9-11--[ Debug ]--Destroy SqQueue OK
    117. 2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
    118. 2023-9-11--[ Debug ]--Two Way Merge Sort Sentry Queue OK.
    119. 2023-9-11--[ Info ]--Sort Function Elapsed Time : 0 s
    120. 2023-9-11--[ Info ]--SqQueue Data :
    121. Data : [ 9 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ]
    122. FrontIndex : 0
    123. RearIndex : 0
    124. SqQueueLen : 11
    125. SqQueueMaxLen : 11
    126. Flag : INT_TYPE_FLAG
    127. 2023-9-11--[ Debug ]--Destroy SqQueue OK

    六、小感慨

    C语言学习-20-归并排序》这篇是一年前写的,虽然实现方法上差不多,但是看到现在和之前的变化,感觉自己又进步了一小点,开心,大家一起加油。

  • 相关阅读:
    MYSQL 数据库企业级架构演变史
    如何以最快速度将Vue接入在线客服系统?
    Nacos注册中心10-Server端(处理服务心跳请求)
    金九银十,刷完这个笔记,17K不能再少了....
    基于springboot人事管理系统java项目介绍
    Java代码审计——ClassLoader 类加载机制
    STM32 | 方式1:手机发送指令,开发板向手机发送温湿度;方式2:手机发送指令,开发板定时向手机发送温湿度。
    数据中台:数据治理概述
    互联网摸鱼日报(2022-12-03)
    java:使用Jedis操作redis
  • 原文地址:https://blog.csdn.net/qq_45111959/article/details/132802052