归并排序算法

打印 上一主题 下一主题

主题 797|帖子 797|积分 2391

归并排序


1算法介绍

和选择排序一样,归并排序的性能不受输入数据的影响,但体现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。归并排序是创建在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。
2根本头脑

根本思路就是将数组分成二组 A,B,如果这二组组内的数据都是有序的,那么就可以 很方便的将这二组数据进行排序。如何让这二组组内数据有序了?
可以将 A,B 组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以以为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。如许通过先递归的分解数列,再合并数列就完成了归并排序。
  1. #include <stdio.h>
  2. void find(int arr[], int left, int mid, int right)
  3. {
  4.     int i, j, k;             // 定义索引变量
  5.     int n1 = mid - left + 1; // 计算左边子数组的长度
  6.     int n2 = right - mid;    // 计算右边子数组的长度
  7.     int L[n1], R[n2];        // 创建左右两个临时数组
  8.     for (i = 0; i < n1; i++)
  9.     {
  10.         L[i] = arr[left + i]; // 将左子数组元素复制到L中
  11.     }
  12.     for (j = 0; j < n2; j++)
  13.     {
  14.         R[j] = arr[mid + 1 + j]; // 将右子数组元素复制到R中
  15.     }
  16.     i = 0;    // 初始化左子数组索引
  17.     j = 0;    // 初始化右子数组索引
  18.     k = left; // 初始化合并后数组的起始位置
  19.     while (i < n1 && j < n2)
  20.     {
  21.         if (L[i] <= R[j])  // 当左右子数组都未完全遍历时,进行合并操作
  22.         {                  // 如果左子数组的当前元素小于等于右子数组的当前元素
  23.             arr[k] = L[i]; // 将左子数组的元素放入合并后的数组
  24.             i++;           // 移动左子数组的索引
  25.         }
  26.         else
  27.         {
  28.             arr[k] = R[j]; // 将右子数组的元素放入合并后的数组
  29.             j++;           // 移动右子数组的索引
  30.         }
  31.         k++; // 移动合并后数组的索引
  32.     }
  33.     while (i < n1)
  34.     {                  // 如果左子数组还有剩余元素
  35.         arr[k] = L[i]; // 将左子数组的剩余元素放入合并后的数组
  36.         i++;           // 移动左子数组的索引
  37.         k++;           // 移动合并后数组的索引
  38.     }
  39.     while (j < n2)
  40.     {                  // 如果右子数组还有剩余元素
  41.         arr[k] = R[j]; // 将右子数组的剩余元素放入合并后的数组
  42.         j++;           // 移动右子数组的索引
  43.         k++;           // 移动合并后数组的索引
  44.     }
  45.     return;
  46. }
  47. void merge(int arr[], int left, int right)
  48. {
  49.     if (left < right)
  50.     {                                        // 如果左边界小于右边界,说明还有多个元素需要排序
  51.         int mid = left + (right - left) / 2; // 计算中点,避免溢出
  52.         merge(arr, left, mid);               // 对左子数组进行归并排序
  53.         merge(arr, mid + 1, right);          // 对右子数组进行归并排序
  54.         find(arr, left, mid, right);         // 合并两个已排序的子数组
  55.     }
  56.     return;
  57. }
  58. int main()
  59. {
  60.     int arr[] = {38, 27, 43, 3, 9, 82, 10};
  61.     int n = sizeof(arr) / sizeof(arr[0]);
  62.     merge(arr, 0, n - 1); // 调用归并排序函数,对数组进行排序
  63.     printf("排序后为: \n");
  64.     for (int i = 0; i < n; i++)
  65.     {
  66.         printf("%d ", arr[i]);
  67.     }
  68.     printf("\n");
  69.     return 0;
  70. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

半亩花草

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表