美文网首页
归并排序(java)

归并排序(java)

作者: castlet | 来源:发表于2020-05-01 16:33 被阅读0次

假设初始序列有n个数字,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2(或1)的有序子序列;再两两归并,如此反复即可。时间复杂度O(nlogn),是稳定的排序算法。非递归实现的性能好于递归的方式。

  8   3   12   5   10
  \  /     \  /    /
 [3 8]   [5 12]  [10]
    \     /       /
   [3 5 8 12]   [10]
       \       /
       [3 5 8 10 12]

代码-递归方式

// 1. 递归算法
void mergeSort(int[] arr) {
    if (arr == null || arr.length <= 0) {
        return;
    }
    int[] tmp = new int[arr.length]; //辅助数组
    mergeSort(arr, tmp, 0, arr.length - 1);
}

void mergeSort(int[] arr, int[] tmp, int start, int end) {
    if (start < end) {
        int middle = start + (end - start) / 2;
        mergeSort(arr, tmp, start, middle);        // 对左边的序列进行归并排序
        mergeSort(arr, tmp, middle + 1, end); //对右边的序列进行归并排序
        merge(arr, tmp, start, middle, end);       // 合并左右两个有序的序列
    }
}

// 将有序的arr[start...middle -1]和arr[middle...end]合并为有序的arr[start...end]
void merge(int[] arr, int[] tmp, int start, int middle, int end){
    if (start >= end) {
        return;
    }
    int i = start;       // 左边序列的索引
    int j = middle + 1;  // 右边序列的索引
    int k = start;       // 合并后有序序列的索引,用tmp来临时保存合并后的有序序列

    while (i <= middle && j <= end) {
        if (arr[i] < arr[j]) {
            tmp[k] = arr[i];
            i++;
        } else {
            tmp[k] = arr[j];
            j++;
        }
        k++;
    }
    if (i <= middle) {
        // 若左边序列还有剩余,则将左边序列剩余数字拷贝到tmp中
        while (i <= middle) {
            tmp[k] = arr[i];
            i++;
            k++;
        }
    } else if (j <= end) {
        // 若右边序列还有剩余,则将右边序列剩余数字拷贝到tmp中
        while (j <= end) {
            tmp[k] = arr[j];
            j++;
            k++;
        }
    }

    // 将tmp里的有序序列拷贝到原始数组中
    for (i = start; i <= end; i++) {
        arr[i] = tmp[i];
    }
}

代码-非递归方式

// 2.非递归算法
void mergeSort2(int[] arr){
    if (arr == null || arr.length <= 0) {
        return;
    }
    int k = 1; // 归并的子序列长度,初始值为1
    int[] tmp = new int[arr.length];
    while (k < arr.length) {
        mergeSort2(arr, tmp, k); // 对长度为k的子序列进行两两归并
        k = k * 2;               // 自序列加倍
    }
}

void mergeSort2(int[] arr, int[] tmp, int k){
    int i = 0;
    while (i + 2 * k <= arr.length) {
        merge(arr, tmp, i, i + k - 1, i + 2 * k - 1); // 分解成两个子序列进行归并
        i = i + 2 * k;
    }

    if (i + k < arr.length) {
        merge(arr, tmp, i, i + k - 1, arr.length - 1); // 归并最后两个子序列
    }
}

相关文章

  • 归并排序

    归并排序Java实现

  • 归并排序

    归并排序 代码实现(java):

  • 常用排序算法的Java实现

    冒泡、插入、选择、归并、快速排序的Java实现

  • 归并排序

    自顶向下的归并排序 java描述

  • 面试知识点

    排序冒泡排序快速排序选择排序插入排序二路归并 查找二分查找 排序和查找的java实现 java语言Java字符串字...

  • Java代码实现归并排序

    Java代码实现归并排序 归并排序(Merge Sort) 思路:如果要排序一个数组,我们先把数组从中间分成前后两...

  • 快排 、 归并排序----复习

    分治思想在归并排序之中可以很好地体现出来。 归并排序: 下面是程序java static public void...

  • 排序算法Java实现

    本文会通过Java语言实现:冒泡排序,插入排序,选择排序,归并排序,快速排序,桶排序,计数排序,基数排序,希尔排序...

  • 排序

    八大排序算法 一、归并排序 递归及非递归的JAVA实现 二、快速排序 快排算法JAVA实现 三、堆排序 堆排序堆排...

  • 排序算法

    约定 选择排序 冒泡排序 插入排序 希尔排序 归并排序1. 归并方法2. 自顶向下归并排序3. 自底向上归并排序 ...

网友评论

      本文标题:归并排序(java)

      本文链接:https://www.haomeiwen.com/subject/utyqghtx.html