美文网首页算法
【排序知多少】归并排序(递归和非递归实现)

【排序知多少】归并排序(递归和非递归实现)

作者: 齐鑫 | 来源:发表于2020-01-09 23:34 被阅读0次

归并排序思路

1、将待排序元素一分为二

2、对于左半边和右半边元素分别再次进行拆分,直到无法再拆

3、把拆分过的元素进行重新排序并且合并

4、合并之后最终的数组即为排序之后的数组

归并排序理解

归并排序适用了完全二叉树排序的想法,将带排列数组逐层均分,尽可能分成完全二叉树的形式,再把每组查分的元素从最底层开始,逐层向上的合并起来,直到再次和成一个有序的数组,即完成整个排序过程。

归并排序复杂度

由于归并排序采用了完全二叉树的形式,根据二叉树的复杂度可知,耗费的时间为O(logn),而且一趟归并排序需要将相邻的元素两两进行归并,即所有待排序元素都要扫描一遍,时间复杂度为O(n),所以,归并排序的总时间复杂度为O(nlogn)。

由于归并排序需要将和原数据同样数量级的存储空间存放归并结果,以及递归时深度为logn的站空间,因此,归并排序的空间复杂度为O(n+logn)。

归并排序特点

由于归并排序中需要两两进行比较,不存在跳跃的比较方式,所以归并排序是一种稳定的排序算法。

综上所述,归并排序是一种比较占用内存空间,但是高效且稳定的排序算法。

归并排序JAVA实现

递归实现

public static void main(String[] args) {
        int[] arr = {2, 56, 2, 13, 54, 23, 1};
        mergeSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
 
    private static void merge(int[] arr, int left, int mid, int right) {
        int[] temp = new int[right - left + 1];
        // p1是左半边指针
        int p1 = left;
        // p2是右半边指针
        int p2 = mid + 1;
        // 合并后数组指针
        int k = 0;
        while (p1 <= mid && p2 <= right) {
            if (arr[p1] < arr[p2]) {
                temp[k++] = arr[p1++];
            } else {
                temp[k++] = arr[p2++];
            }
        }
        while (p1 <= mid) {
            temp[k++] = arr[p1++];
        }
        while (p2 <= right) {
            temp[k++] = arr[p2++];
        }
        for (int i = 0; i < temp.length; i++) {
            arr[left + i] = temp[i];
        }
    }
 
    private static void mergeSort(int[] arr, int start, int end) {
        if (start < end) {
            int mid = (start + end) / 2;
            mergeSort(arr, start, mid);
            mergeSort(arr, mid + 1, end);
            merge(arr, start, mid, end);
        }
    }
}

非递归实现

public class Main {
    public static void main(String[] args) {
        int[] arr = {2, 56, 2, 13, 54, 23, 1};
        mergeSort(arr);
        System.out.println(Arrays.toString(arr));
    }
 
    private static void mergeSort(int[] arr) {
        // 使用非递归方式实现归并排序
        int len = arr.length;
        int k = 1;
        while (k < len) {
            mergePass(arr, k, len);
            k *= 2;
        }
    }
 
    private static void mergePass(int[] arr, int k, int n) {
        int i = 0;
        // 从前往后走,将2个长度为k的子序列合并为1个
        while (i < n - 2 * k + 1) {
            merge(arr, i, i + k - 1, i + 2 * k - 1);
            i += 2 * k;
        }
        // 这段代码保证了,讲那些落单的长度不足两两merge的部分和前面merge起来
        if (i < n - k) {
            merge(arr, i, i + k - 1, n - 1);
        }
    }
 
    private static void merge(int[] arr, int left, int mid, int right) {
        int[] temp = new int[right - left + 1];
        // p1是左半边指针
        int p1 = left;
        // p2是右半边指针
        int p2 = mid + 1;
        // 合并后数组指针
        int k = 0;
        while (p1 <= mid && p2 <= right) {
            if (arr[p1] < arr[p2]) {
                temp[k++] = arr[p1++];
            } else {
                temp[k++] = arr[p2++];
            }
        }
        while (p1 <= mid) {
            temp[k++] = arr[p1++];
        }
        while (p2 <= right) {
            temp[k++] = arr[p2++];
        }
        for (int i = 0; i < temp.length; i++) {
            arr[left + i] = temp[i];
        }
    }
}

相关文章

  • 三大排序算法

    归并排序[稳定的排序算法] 递归实现 非递归实现 快速排序[不稳定的排序算法] 堆排序[不稳定的排序算法]

  • 多线程归并排序 go实现

    特性 线程数可以调整 混合使用归并排序的递归版和非递归版实现减少递归调用损耗 线程利用率高 不足:归并排序的mer...

  • 排序

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

  • java归并排序

    归并排序什么是归并排序:图解归并排序归并排序有两种实现方式,一是基于递归,而是基于迭代1)基于递归的归并排序: 基...

  • 2020-08-21 算法合集

    1. 冒泡排序 2.选择排序 3. 插入排序 4. 希尔排序 5. 归并排序(递归实现) 6. 快速排序(递归实现...

  • 【排序知多少】归并排序(递归和非递归实现)

    归并排序思路 1、将待排序元素一分为二 2、对于左半边和右半边元素分别再次进行拆分,直到无法再拆 3、把拆分过的元...

  • PHP数组示例算法

    1、冒泡排序 2、归并排序 3、二分查找-递归 4、二分查找-非递归 5、快速排序 6、选择排序 7、插入排序

  • 常见排序算法(6)--归并排序(非递归版)

    非递归归并排序算法 非递归排序与递归排序相反,将一个元素与相邻元素构成有序数组,再与旁边数组构成有序数组,直至整个...

  • 归并排序的递归实现与非递归实现

    归并排序 归并排序图 递归实现简介代码示例 mergesort(left,right,**a){ if(l...

  • 算法排序之归并排序和快速排序

    归并排序和快速排序用的都是分治的思想,用递归的编程技巧来实现.咱们先来看归并排序. 归并排序 归并排序的核心思想就...

网友评论

    本文标题:【排序知多少】归并排序(递归和非递归实现)

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