zoukankan      html  css  js  c++  java
  • 归并排序

    算法思想


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

    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
    
  • 相关阅读:
    STL应用 map poj 2418
    STL应用 set hdu 1412
    STL应用 deque hdu 6375
    STL应用 queue poj 1915
    STL应用 map HDU 3527
    算法训练营 入门篇 STL应用 vector HDU 3527
    算法训练营:海量图解+竞赛刷题(入门篇)刷题, 算法基础知识点讲解与练习
    BFS 遍历例子
    【知识】MySQL索引原理及慢查询优化
    【MySQL优化】——看懂explain
  • 原文地址:https://www.cnblogs.com/freelancy/p/8193755.html
Copyright © 2011-2022 走看看