zoukankan      html  css  js  c++  java
  • 算法八之归并排序

    一、归并排序原理

      归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
      归并过程为:比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
     

    二、算法实现

    package cn.edu.scau.mk;
    
    import java.util.Arrays;
    
    /**
     *
     * @author MK
     */
    public class MergeSort {
        
        public static void mergeSort(int[] data) {
            mergeSortCall(data, 0, data.length-1);
        }
        
        /**
         * 归并递归
         * @param data 序列
         * @param low  开始
         * @param high 末尾
         */
        private static void mergeSortCall(int[] data,int low,int high) {
            
            if(low<high){
                int mid=(low+high)/2;
                mergeSortCall(data,low,mid);  //左边递归
                mergeSortCall(data, mid+1, high);//右边递归
                mergeUnit(data,low,mid,high); //合并
            }
        }
    
        /**
         * 合并
         * @param data 序列
         * @param low  起始
         * @param mid  中间
         * @param high  末尾
         */
        private static void mergeUnit(int[] data, int low, int mid, int high) {
            int n1=mid-low+1;
            int n2=high-mid;
            
            
            int[] d1=new int[n1];
            int[] d2=new int[n2];
            System.arraycopy(data, low, d1, 0, n1);// data[low..mid]复制到d1
            System.arraycopy(data, mid+1, d2, 0, n2);//data[mid+1..high]复制到d2
            
            int i=0;
            int j=0;
            int k=low;
            //开始合并两个序列
            while (i<n1&&j<n2) {            
                if(d1[i]<d2[j]){
                    data[k]=d1[i++];
                }else{
                    data[k]=d2[j++];
                }
                k++;
            }
            //剩余的d1追加到后面
            while (i<n1) {            
                 data[k++]=d1[i++];
            }
            //剩余的d2追加到后面
            while (j<n2) {            
                 data[k++]=d2[j++];
            }
        }
        
        public static void main(String[] args) {
            int[]  data={2,1,5,-2};
            mergeSort(data);
            System.out.println(Arrays.toString(data));
            
        }
    }

    三、算法复杂度

    最好时间O(nlogn),最坏时间O(nlogn),平均时间O(nlogn),算法稳定,空间复杂度O(n)。n越大时候,算法效率越好。

  • 相关阅读:
    Python-list
    C3P0数据库连接池使用中的问题
    不变类和可变类
    apollo配置中心部署文档
    Apollo使用文档(Java)
    Redis偶发连接失败案例分析
    创建Kibana耗时报表
    Session服务器配置,如何保存在专门的StateServer服务器中
    Linux命令对应的英文全称
    IIS记录真实来源IP,Advanced Logging(高级日志)的安装以及X-Forwarded-For的配置
  • 原文地址:https://www.cnblogs.com/maokun/p/7354827.html
Copyright © 2011-2022 走看看