算法 排序算法之归并排序

拼搏现实的明天。 2022-06-15 12:56 364阅读 0赞

归并排序

归并排序主要是二路归并排序

基本思想

  • 设数组a中存放了n个数据元素
  • 初始时把它们看成n个长度为1的有序子数组,然后从第一个子数组开始,把相邻子数组两两合并,得到n/2的整数上界个长度为2的新的有序子数组(当n为奇数时最后一个新的有序子数组的长度为1)
  • 对这些新的有序子数组再两两合并,直到最后长度为n的有序数组位置

排序过程

这里写图片描述

以数组{50,10,90,30,70,40,80,60,20}为例

这里写图片描述

代码实现

  1. void Merge(DataType a[], int n, DataType swap[], int k) {
  2. /*k为有序子数组的长度,一次二路归并排序后的有序子序列放在数组swap中*/
  3. int m = 0, u1, l2, i, j, u2;
  4. /*第一个有序子数组下界为0*/
  5. int l1 = 0;
  6. while (l1 + k <= n - 1) {
  7. l2 = l1 + k;//计算第二个有序子数组下界
  8. u1 = l2 - 1;//计算第一个有序子数组上界
  9. u2 = (l2 + k - 1 <= n - 1) ? l2 + k - 1 : n - 1;//计算第二个有序子数组上界
  10. /*两个有序子数组合并*/
  11. for (i = l1, j = l2; i <= u1 && j <= u2; m++) {
  12. if (a[i] <= a[j]) {
  13. swap[m] = a[i];
  14. i++;
  15. } else {
  16. swap[m] = a[j];
  17. j++;
  18. }
  19. }
  20. /*子数组2已归并完,将数组1中剩余的元素放到数组swap中*/
  21. while (i <= u1) {
  22. swap[m] = a[i];
  23. m++;
  24. i++;
  25. }
  26. /*子数组1已归并完,将数组2中剩余的元素放到数组swap中*/
  27. while (j <= u2) {
  28. swap[m] = a[j];
  29. m++;
  30. j++;
  31. }
  32. l1 = u2 + 1;
  33. }
  34. /*将原始数组中只够一组的元素顺序放到数组swap中*/
  35. for (i = l1; i < n; i++, m++) {
  36. swap[m] = a[i];
  37. }
  38. }
  39. void MergeSort(DataType a[], int n) {
  40. int i, k = 1;//归并长度从1开始
  41. DataType * swap;
  42. swap = (DataType *) malloc(sizeof(DataType) * n);
  43. while (k < n) {
  44. Merge(a, n, swap, k);
  45. for (i = 0; i < n; i++) {
  46. a[i] = swap[i];
  47. }
  48. k = 2 * k;
  49. }
  50. free(swap);
  51. }

java实现

  1. public static void mergeSort(int[] arr) {
  2. mergeSort(arr, 0, arr.length - 1);
  3. }
  4. private static void mergeSort(int[] arr, int low, int high) {
  5. int mid = (low + high) / 2;
  6. if (low < high) {
  7. //左边
  8. mergeSort(arr, low, mid);
  9. //右边
  10. mergeSort(arr, mid + 1, high);
  11. //左右归并
  12. merge(arr, low, mid, high);
  13. }
  14. }
  15. private static void merge(int[] arr, int low, int mid, int high) {
  16. int[] temp = new int[high - low + 1];
  17. int left = low;//左指针
  18. int right = mid + 1;//右指针
  19. int k = 0;
  20. //把较小的数先移动到新数组中
  21. while (left <= mid && right <= high) {
  22. if (arr[left] < arr[right]) {
  23. temp[k++] = arr[left++];
  24. } else {
  25. temp[k++] = arr[right++];
  26. }
  27. }
  28. //把左边剩余的数移入数组
  29. while (left <= mid) {
  30. temp[k++] = arr[left++];
  31. }
  32. //把右边剩余的数移入数组
  33. while (right <= high) {
  34. temp[k++] = arr[right++];
  35. }
  36. //把新数组中的数覆盖nums数组
  37. for (int k2 = 0; k2 < temp.length; k2++) {
  38. arr[k2 + low] = temp[k2];
  39. }
  40. }

算法分析

  • 时间复杂度
  1. * 一次二路归并排序归并的次数log2n 每次比较次数n-1 故时间复杂度是O(nlog2n)
  • 空间复杂度
  1. * 使用了n个临时内存单元存放数据 空间复杂度O(n)
  • 稳定性
  1. * 归并排序是一种**比较占内存**,但却**效率高且稳定**的算法

发表评论

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

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

相关阅读

    相关 排序算法归并排序

    归并排序是一种基于分治思想的排序算法,它的基本思路是将原始序列划分为若干个子序列,对每个子序列进行排序,然后将排好序的子序列合并为一个大序列,最终得到排序结果。具体来说,归并排

    相关 排序算法归并排序

    归并排序 基本思想:归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使用每个子序列有

    相关 排序算法归并排序

    归并排序> 之前曾经实现过堆排序,它用到了完全二叉树,但是堆的设计本身就是比较复杂的,而今天要实现的归并排序同样的也用到了完全二叉树的思想,这种思想比堆排序较为简单.

    相关 排序算法归并排序

    归并排序是利用递归与分治思想将数据序列划分成越来越小的半子序列,在对其进行排序,最后利用递归将排好序的半子序列合并成越来越大的有序序列。 归并排序中,归 即是递归的意思,即递