栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

排序算法(5)--归并排序

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

排序算法(5)--归并排序

归并排序
  • 1.1 递归实现
  • 1.2 非递归实现

关于归并排序也是有两种实现方式, 递归实现和非递归实现, 其思路如下.

1.1 递归实现

**递归实现归并排序的基本思想: 就是一直对半分, 直到分到剩下一个或者是两个元素的时候为止, 然后对分开到最后的小序列进行排序比较, 比较完后回到上一层的序列中再次进行比较, 直到序列整体有序. **
详细过程如下:

代码如下:

public class MergeSort {
    
    public static void merge(int[] arr, int low, int mid, int high) {
        int s1 = low;
        int e1 = mid;
        int s2 = mid + 1;
        int e2 = high;

        int[] tmp = new int[high - low + 1];
        int k = 0; // 代表 tmp 数组的下标

        while (s1 <= e1 && s2 <= e2) {
            if (arr[s1] <= arr[s2]) {
                tmp[k++] = arr[s1++];
            } else {
                tmp[k++] = arr[s2++];
            }
        }
        // 有两种情况
        while (s1 <= e1) {
            // 说明第二个归并段没有了数据, 把第一个归并段剩下的数据全部拷过来
            tmp[k++] = arr[s1++];
        }
        while (s2 <= e2) {
            // 说明第一个归并段没有了, 把第二个归并段剩下的数据全部拷贝过来
            tmp[k++] = arr[s2++];
        }
        // tmp 数组当中, 存储的就是当前归并好的数据
        for (int i = 0; i < tmp.length; i++) {
            arr[i + low] = tmp[i];
        }
    }

    public static void mergeSortInternal(int[] arr, int low, int high) {
        if (low >= high) {
            return;
        }
        int mid = (low + high) / 2;
        mergeSortInternal(arr, low, mid);
        mergeSortInternal(arr, mid + 1, high);
        // 合并的过程
        merge(arr, low, mid, high);
    }

    public static void mergeSort1(int[] arr) {
        mergeSortInternal(arr, 0, arr.length - 1);
    }

    public static void main(String[] args) {
        int[] arr = {3,2,5,7,1,6,8,9,4};
        System.out.println(Arrays.toString(arr));
        mergeSort1(arr);
        System.out.println(Arrays.toString(arr));
    }
}

运行结果:

性能分析:

1.2 非递归实现

对于非递归来实现的基本思想就是先从 i = 1开始, 对 i*2 的序列进行排序, 如下图所示, 首先对 3,2 进行排序, 然后再对 2,3,5,7 进行排序, 然后再对 1,2,3,5,6,7,8,9 八个元素进行排序, 最后再对所有元素进行排序.
详细思路如下:

代码如下:

public class MergeSort {
    public static void merge2(int[] arr, int gap) {
        int[] tmp = new int[arr.length];
        int k = 0;

        int s1 = 0;
        int e1 = s1 + gap - 1;
        int s2 = e1 + 1;
        int e2 = s2 + gap - 1 < arr.length ? s2 + gap - 1 : arr.length - 1;

        // 需要保证有两个归并段
        while (s2 < arr.length) {
            while (s1 <= e1 && s2 <= e2) {
                if (arr[s1] <= arr[s2]) {
                    tmp[k++] = arr[s1++];
                } else {
                    tmp[k++] = arr[s2++];
                }
            }
            while (s1 <= e1) {
                tmp[k++] = arr[s1++];
            }
            while (s2 <= e2) {
                tmp[k++] = arr[s2++];
            }
            // 一组完成后, 确定新的区间的开始和结束
            s1 = e2 + 1;
            e1 = s1 + gap - 1;
            s2 = e1 + 1;
            e2 = s2 + gap - 1 < arr.length ? s2 + gap - 1 : arr.length - 1;
        }
        while (s1 <= arr.length - 1) {
            tmp[k++] = arr[s1++];
        }
        for (int i = 0; i < tmp.length; i++) {
            arr[i] = tmp[i];
        }
    }
    public static void mergeSort2(int[] arr) {
        for (int i = 1 ; i < arr.length; i*=2) {
            merge2(arr, i);
        }
}


    public static void main(String[] args) {
        int[] arr = {3,2,5,7,1,6,8,9,4};
        System.out.println(Arrays.toString(arr));
        mergeSort2(arr);
        System.out.println(Arrays.toString(arr));
    }
}

运行结果:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1014934.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号