【大话数据结构C语言】69 归并排序(递归和迭代实现)

举报
CodeAllen 发表于 2021/10/29 22:48:35 2021/10/29
【摘要】 堆排序之所以效率比较高是利用了完全二叉树,但是堆排序的设计本身是比较复杂的 那就引出一个问题,有没有更简单的使用完全二叉树来排序的算法呢?   这就引出了归并排序算法   归并排序 归并排序就是利用归并的思想实现的排序方法,原理是假设初始序列含有n个记录,则可以看出是n个...
堆排序之所以效率比较高是利用了完全二叉树,但是堆排序的设计本身是比较复杂的
那就引出一个问题,有没有更简单的使用完全二叉树来排序的算法呢?
 
这就引出了归并排序算法
 

归并排序

归并排序就是利用归并的思想实现的排序方法,原理是假设初始序列含有n个记录,则可以看出是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或者1的有序子序列;再两两归并。。。。如此反复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路规定排序
 
其排序的过程就是完全二叉树

时间复杂度

归并排序的时间复杂度也是nlogn,且这是归并排序中最好,最坏,平均的时间性能,因此归并排序是一种稳定的排序

其空间复杂度为n+logn

 

也就是说,归并排序是一种比较占用内存,但是效率高且稳定的算法

递归实现:


   
  1. #include <stdio.h>
  2. #define MAXSIZE 10
  3. // 实现归并,并把最后的结果存放到list1里
  4. void merging(int *list1, int list1_size, int *list2, int list2_size)
  5. {
  6. int i, j, k, m;
  7. int temp[MAXSIZE];
  8. i = j = k = 0;
  9. while( i < list1_size && j < list2_size )
  10. {
  11. if( list1[i] < list2[j] )
  12. {
  13. temp[k++] = list1[i++];
  14. }
  15. else
  16. {
  17. temp[k++] = list2[j++];
  18. }
  19. }
  20. while( i < list1_size )
  21. {
  22. temp[k++] = list1[i++];
  23. }
  24. while( j < list2_size )
  25. {
  26. temp[k++] = list2[j++];
  27. }
  28. for( m=0; m < (list1_size + list2_size); m++ )
  29. {
  30. list1[m] = temp[m];
  31. }
  32. }
  33. void MergeSort(int k[], int n)
  34. {
  35. if( n > 1)
  36. {
  37. int *list1 = k;
  38. int list1_size = n/2;
  39. int *list2 = k + n/2;
  40. int list2_size = n - list1_size;
  41. MergeSort(list1, list1_size);
  42. MergeSort(list2, list2_size);
  43. merging(list1, list1_size, list2, list2_size);
  44. }
  45. }
  46. int main()
  47. {
  48. int i, a[10] = {5, 2, 6, 0, 3, 9, 1, 7, 4, 8};
  49. MergeSort(a, 10);
  50. printf("排序后的结果是:");
  51. for( i=0; i < 10; i++ )
  52. {
  53. printf("%d", a[i]);
  54. }
  55. printf("\n\n");
  56. return 0;
  57. }

非递归实现归并排序(迭代实现)

 
 
递归本身是有限制的(时间和空间上的性能损耗),之前也说过,大多数递归都是可以改造为迭代

    
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define MAXSIZE 10
  4. void MergeSort(int k[], int n)
  5. {
  6. int i, next, left_min, left_max, right_min, right_max;
  7. int *temp = (int *)malloc(n * sizeof(int));
  8. for( i=1; i < n; i*=2 )
  9. {
  10. for( left_min=0; left_min < n-i; left_min = right_max )
  11. {
  12. right_min = left_max = left_min + i;
  13. right_max = left_max + i;
  14. if( right_max > n )
  15. {
  16. right_max = n;
  17. }
  18. next = 0;
  19. while( left_min < left_max && right_min < right_max )
  20. {
  21. if( k[left_min] < k[right_min] )
  22. {
  23. temp[next++] = k[left_min++];
  24. }
  25. else
  26. {
  27. temp[next++] = k[right_min++];
  28. }
  29. }
  30. while( left_min < left_max )
  31. {
  32. k[--right_min] = k[--left_max];
  33. }
  34. while( next > 0 )
  35. {
  36. k[--right_min] = temp[--next];
  37. }
  38. }
  39. }
  40. }
  41. int main()
  42. {
  43. int i, a[10] = {5, 2, 6, 0, 3, 9, 1, 7, 4, 8};
  44. MergeSort(a, 10);
  45. printf("排序后的结果是:");
  46. for( i=0; i < 10; i++ )
  47. {
  48. printf("%d", a[i]);
  49. }
  50. printf("\n\n");
  51. return 0;
  52. }

 

 

文章来源: allen5g.blog.csdn.net,作者:CodeAllen的博客,版权归原作者所有,如需转载,请联系作者。

原文链接:allen5g.blog.csdn.net/article/details/117195559

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。