排序算法:归并排序算法实现及分析

末蓝、 2022-05-31 12:36 385阅读 0赞

归并排序算法介绍

归并排序(Merging Sort)就是利用归并的思想实现排序的放。它的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或1的有序子序列;再两两归并,…..,如此重复,直到得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序。

归并排序算法图解

20180224235827721

归并排序算法代码

其实归并排序思路很好理解,就是将2个有序的序列合并,整个序列都是无序的哪里去找有序的序列?我们可以无限递归,将其划分为1个元素的序列,这时肯定是有序的咯,然后一路归并排序 就ok呀。主要是合并代码,仔细看 是不是应该这样去合并!

  1. //归并排序的合并数组函数 升序
  2. void Merge_Up(int *arr, int start, int mid, int end, int *temp)
  3. {
  4. int i_start = start;
  5. int i_end = mid;
  6. int j_start = mid + 1;
  7. int j_end = end;
  8. int length = 0;
  9. while (i_start <= i_end && j_start <= j_end)
  10. {
  11. //升序 我小先放我
  12. if (arr[i_start] < arr[j_start])
  13. {
  14. temp[length] = arr[i_start];
  15. length++;
  16. i_start++;
  17. }
  18. else
  19. {
  20. temp[length] = arr[j_start];
  21. length++;
  22. j_start++;
  23. }
  24. }
  25. //将剩余没有放完的放置到辅助空间中去
  26. while (i_start <= i_end)
  27. {
  28. temp[length] = arr[i_start];
  29. length++;
  30. i_start++;
  31. }
  32. while (j_start <= j_end)
  33. {
  34. temp[length] = arr[j_start];
  35. length++;
  36. j_start++;
  37. }
  38. //将辅助空间的值复制到源数组
  39. for (int i = 0; i < length; i++)
  40. {
  41. arr[start + i] = temp[i];
  42. }
  43. return;
  44. }
  45. /*
  46. 归并排序
  47. @param arr 归并排序的数组
  48. @param start 开始下标
  49. @param end 结束下标
  50. @param temp 辅助空间
  51. */
  52. void MergeSort_Up(int *arr,int start,int end,int* temp)
  53. {
  54. if (start >= end)
  55. {
  56. return;
  57. }
  58. int mid = (start + end )/ 2;
  59. //分组
  60. //左半部分 进行归并排序
  61. MergeSort_Up(arr, start, mid, temp);
  62. //右半部分 进行归并排序
  63. MergeSort_Up(arr, mid + 1, end, temp);
  64. //合并排序好的2个数组
  65. Merge_Up(arr, start, mid, end, temp);
  66. }

完整代码

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #include <sys/timeb.h>
  6. #define MAXSIZE 1000000
  7. //交换值
  8. void Swap(int* a, int* b)
  9. {
  10. int temp = *a;
  11. *a = *b;
  12. *b = temp;
  13. }
  14. //打印数组元素
  15. void PrintArr(int* arr, int length)
  16. {
  17. for (int i = 0; i < length; i++)
  18. {
  19. printf("%d ", arr[i]);
  20. }
  21. printf("\n");
  22. return;
  23. }
  24. long GetSysTime()
  25. {
  26. struct timeb tb;
  27. ftime(&tb);
  28. return tb.time * 1000 + tb.millitm;
  29. }
  30. //归并排序的合并数组函数 降序
  31. void Merge_Down(int *arr, int start, int mid, int end, int *temp)
  32. {
  33. int i_start = start;
  34. int i_end = mid;
  35. int j_start = mid + 1;
  36. int j_end = end;
  37. int length = 0;
  38. //只有 1个元素时肯定是有序的,做为递归函数的出口。
  39. if (start >= end)
  40. {
  41. return;
  42. }
  43. while (i_start <= i_end && j_start <= j_end)
  44. {
  45. //降序 我大先放我
  46. if (arr[i_start] > arr[j_start])
  47. {
  48. temp[length] = arr[i_start];
  49. length++;
  50. i_start++;
  51. }
  52. else
  53. {
  54. temp[length] = arr[j_start];
  55. length++;
  56. j_start++;
  57. }
  58. }
  59. //将辅助空间的值复制到源数组
  60. for (int i = 0; i < length; i++)
  61. {
  62. arr[start + i] = temp[i];
  63. }
  64. }
  65. //归并排序的合并数组函数 升序
  66. void Merge_Up(int *arr, int start, int mid, int end, int *temp)
  67. {
  68. int i_start = start;
  69. int i_end = mid;
  70. int j_start = mid + 1;
  71. int j_end = end;
  72. int length = 0;
  73. while (i_start <= i_end && j_start <= j_end)
  74. {
  75. //升序 我小先放我
  76. if (arr[i_start] < arr[j_start])
  77. {
  78. temp[length] = arr[i_start];
  79. length++;
  80. i_start++;
  81. }
  82. else
  83. {
  84. temp[length] = arr[j_start];
  85. length++;
  86. j_start++;
  87. }
  88. }
  89. //将剩余没有放完的放置到辅助空间中去
  90. while (i_start <= i_end)
  91. {
  92. temp[length] = arr[i_start];
  93. length++;
  94. i_start++;
  95. }
  96. while (j_start <= j_end)
  97. {
  98. temp[length] = arr[j_start];
  99. length++;
  100. j_start++;
  101. }
  102. //将辅助空间的值复制到源数组
  103. for (int i = 0; i < length; i++)
  104. {
  105. arr[start + i] = temp[i];
  106. }
  107. return;
  108. }
  109. /*
  110. 归并排序
  111. @param arr 归并排序的数组
  112. @param start 开始下标
  113. @param end 结束下标
  114. @param temp 辅助空间
  115. */
  116. void MergeSort_Up(int *arr,int start,int end,int* temp)
  117. {
  118. if (start >= end)
  119. {
  120. return;
  121. }
  122. int mid = (start + end )/ 2;
  123. //分组
  124. //左半部分 进行归并排序
  125. MergeSort_Up(arr, start, mid, temp);
  126. //右半部分 进行归并排序
  127. MergeSort_Up(arr, mid + 1, end, temp);
  128. //合并排序好的2个数组
  129. Merge_Up(arr, start, mid, end, temp);
  130. }
  131. int main(int argc, char *argv[])
  132. {
  133. srand((size_t)time(NULL));//设置随机种子
  134. int arr[10] = { 6,8,2,3,9,7,4,1,5,10 };
  135. int *arr2 = (int*)malloc(sizeof(int)*MAXSIZE);
  136. //int *arr3 = (int*)malloc(sizeof(int)*MAXSIZE);
  137. //给每个元素设置一个随机值
  138. for (int i = 0; i < MAXSIZE; i++)
  139. {
  140. int num = rand() % MAXSIZE;
  141. arr2[i] = num;
  142. //arr3[i] = num;
  143. }
  144. int *temp = (int*)malloc(sizeof(int)*10);
  145. int *temp1 = (int*)malloc(sizeof(int) * MAXSIZE);
  146. printf("排序前:\n");
  147. PrintArr(arr, 10);
  148. MergeSort_Up(arr, 0, 9, temp);
  149. printf("归并排序升序:\n");
  150. PrintArr(arr, 10);
  151. long start = GetSysTime();
  152. MergeSort_Up(arr2, 0, MAXSIZE - 1, temp1);
  153. long end = GetSysTime();
  154. printf("%d个元素 归并排序耗费%d毫秒\n",MAXSIZE,end-start);
  155. return 0;
  156. }

代码运行检测

20180225001019773

发表评论

表情:
评论列表 (有 0 条评论,385人围观)

还没有评论,来说两句吧...

相关阅读

    相关 排序算法——归并排序

    引言 归并排序可以使用递归或迭代的方式来实现,时间复杂度是都是 O(N \ logN)。 归并排序的核心是将待排序数组分组,可以整体二分,也可以设置步长迭代切分。归并排

    相关 排序算法-归并排序

    归并排序也是一个比较快速的排序算法,其思想是运用分治的思想,先对要排序的数进行分,每次从中间分成两部分,然后知道分成最小,然后在把他们合起来,边合起来边排序,最后有序,每次分的

    相关 排序算法归并排序

    一、前言     归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用 分治法(Divide and Conquer) 的一个非常典型的应用。 --------