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

    归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。
      将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
      最佳情况:T(n) = O(n) 最差情况:T(n) = O(nlogn) 平均情况:T(n) = O(nlogn)
    2-路归并的具体解析:
      1)将序列分成左右子序列
      2)再将左右子序列分成左右子序列,直至分成子序列都小于2
      3)将左右子序列进行排序后归并到一起在进行归并排序
      补充:需要额外的空间

      

    package sort;
    /**
     * @author wyc
     * 归并排序
     * 思路:先递归分解,然后在底层合并
     */
    public class MergeSort {
        public static void main(String[] args) {
            int[] arrays = {1,11,12,4,2,6,9,0,3,7,8,2};
            mergeSort(arrays);
            for(int value : arrays){
                System.out.print(value+",");
            }
        }
        
        private static void mergeSort(int[] array) {
             if(array == null && array.length == 0){
                 return;
             }
             int[] temp = new int[array.length];
             mergeSort(array, 0, array.length-1, temp);
        }
        
        private static void mergeSort(int array[], int first, int last, int temp[]) {
            if(first < last){
                int mid = (first + last) / 2;
                mergeSort(array, first, mid, temp);
                mergeSort(array, mid+1, last, temp);
                mergeArray(array, first, mid, last, temp);
            }
        }
        
    
        /**
         * 合并两个有序数列
         * array[first]~array[mid]为第一组
         * array[mid+1]~array[last]为第二组
         * temp[]为存放两组比较结果的临时数组
         */
        private static void mergeArray(int array[], int first, int mid, int last, int temp[]) {
            int i = first, j = mid + 1; // i为第一组的起点, j为第二组的起点
            int m = mid, n = last; // m为第一组的终点, n为第二组的终点
            int k = 0; // k用于指向temp数组当前放到哪个位置
            while (i <= m && j <= n) { // 将两个有序序列循环比较, 填入数组temp
                if (array[i] <= array[j])
                    temp[k++] = array[i++];
                else
                    temp[k++] = array[j++];
            }
            while (i <= m) { // 如果比较完毕, 第一组还有数剩下, 则全部填入temp
                temp[k++] = array[i++];
            }
            while (j <= n) {// 如果比较完毕, 第二组还有数剩下, 则全部填入temp
                temp[k++] = array[j++];
            }
            for (i = 0; i < k; i++) {// 将排好序的数填回到array数组的对应位置
                array[first + i] = temp[i];
            }
        }
    }
  • 相关阅读:
    [SHOI2008]堵塞的交通
    [SHOI2008]汉诺塔
    [JSOI2008]最小生成树计数
    [JSOI2008]球形空间产生器
    [HNOI2014]画框
    HDU 2255 奔小康赚大钱
    [SDOI2017]新生舞会
    [BZOJ2285][SDOI2011]保密
    [BZOJ3232]圈地游戏
    [HDU5909]Tree Cutting
  • 原文地址:https://www.cnblogs.com/nyhhd/p/12605785.html
Copyright © 2011-2022 走看看