• 归并排序


    算法思想


    • 归并思想:将两个有序的数组归并成一个更大的有序的数组
    • 归并过程
      • 现有两个有序的数组
      • 申请第三个、大于等于已有的两个数组长度之和的大叔组
      • 循环将两个小数组有序的存放在大叔组里面

    Java


    • 源码(自顶向下)
    public class Merge {
        
        private static Comparable[] aux;// 归并所需的辅助数组
    
        public static void sort(Comparable[] a) {
            aux = new Comparable[a.length];// 一次性分配空间
            sort(a, 0, a.length - 1);
        }
    
        // 将数组a[lo..hi]排序
        private static void sort(Comparable[] a, int lo, int hi) {
            if (hi <= lo) return;
            int mid = lo + (hi - lo) / 2;
            sort(a, lo, mid);// 将左半边排序
            sort(a, mid + 1, hi);// 将右半边排序
            merge(a, lo, mid, hi);// 归并结果
        }
    
        // 将a[lo..mid]和a[mid+1..hi]归并
        public static void merge(Comparable[] a, int lo, int mid, int hi) {
            int i = lo, j = mid + 1;
    
            for (int k = lo; k <= hi; k++)// 将a[lo..hi]复制到aux[lo..hi]
                aux[k] = a[k];
    
            for (int k = lo; k <= hi; k++)// 归并回到a[lo..hi]
                if (i > mid) a[k] = aux[j++];
                else if (j > hi) a[k] = aux[i++];
                else if (less(aux[j], aux[i])) a[k] = aux[j++];
                else a[k] = aux[i++];
        }
    
        private static boolean less(Comparable v, Comparable w) {
            return v.compareTo(w) < 0;
        }
    
        // 测试数组元素是否有序
        public static boolean isSorted(Comparable[] a) {
            for (int i = 1; i < a.length; i++)
                if (less(a[i], a[i - 1])) return false;
            return true;
        }
    
        // 在单行中打印数组
        public static void show(Comparable[] a) {
            for (int i = 0; i < a.length; i++)
                System.out.print(a[i] + " ");
            System.out.println();
        }
    }
    
    • 源码(自底向上)
    public class Merge {
    
        private static Comparable[] aux;// 归并所需的辅助数组
    
        // 进行lgN次两两归并
        public static void sort(Comparable[] a) {
            int N = a.length;
            aux = new Comparable[N];
            for (int sz = 1; sz < N; sz = sz + sz)// sz子数组大小
                for (int lo = 0; lo < N - sz; lo += sz + sz)// lo:子数组索引
                    merge(a, lo, lo + sz - 1, Math.min(lo + sz + sz - 1, N - 1));
        }
    
        // 将a[lo..mid]和a[mid+1..hi]归并
        public static void merge(Comparable[] a, int lo, int mid, int hi) {
            int i = lo, j = mid + 1;
    
            for (int k = lo; k <= hi; k++)// 将a[lo..hi]复制到aux[lo..hi]
                aux[k] = a[k];
    
            for (int k = lo; k <= hi; k++)// 归并回到a[lo..hi]
                if (i > mid) a[k] = aux[j++];
                else if (j > hi) a[k] = aux[i++];
                else if (less(aux[j], aux[i])) a[k] = aux[j++];
                else a[k] = aux[i++];
        }
    
        private static boolean less(Comparable v, Comparable w) {
            return v.compareTo(w) < 0;
        }
    
        // 测试数组元素是否有序
        public static boolean isSorted(Comparable[] a) {
            for (int i = 1; i < a.length; i++)
                if (less(a[i], a[i - 1])) return false;
            return true;
        }
    
        // 在单行中打印数组
        public static void show(Comparable[] a) {
            for (int i = 0; i < a.length; i++)
                System.out.print(a[i] + " ");
            System.out.println();
        }
    }
    
    • 测试用例
    public class Test {
        public static void main(String[] args) {
    
            String[] test = {"S", "O", "R", "T", "E", "X", "A", "M", "P", "L", "E"};
            Merge.sort(test);
            assert Merge.isSorted(test);
            Merge.show(test);
        }
    }
    
    • 测试结果
    A E E L M O P R S T X
    
  • 相关阅读:
    Ubuntu安装php7.0环境
    PHP-FPM参数详情
    phpize是干嘛的
    Ubuntu忘记密码
    Ubuntu下面删除和卸载软件
    Js验证正则表达式
    JS发送验证码;并设置cookie
    Shell脚本之sed的使用
    Bash基本功能:输入输出重定向
    shell常用快捷键
  • 原文地址:https://www.cnblogs.com/freelancy/p/8193755.html
Copyright © 2020-2023  润新知