zoukankan      html  css  js  c++  java
  • 算法导论:归并排序

    归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

    归并操作(merge),指的是将两个已经排序的序列合并成一个序列的操作。

    对两个排序数组合并成一个有序数组,这个很简单

        public int[] merge(int[] A,int[] B){
            int aLen = A.length;
            int bLen = B.length;
            int cLen = aLen + bLen;
            int[] C = new int[cLen];
            int i=0;
            int j=0;
            int k=0;
            while(i<aLen && j<bLen){
                if(A[i] <= B[j]){
                    C[k] = A[i];
                    k++;
                    i++;
                }else{
                    C[k] = B[j];
                    k++;
                    j++;
                }
            }
            while(i<aLen){
                C[k] = A[i];
                k++;
                i++;
            }
            while(j<bLen){
                C[k] = B[j];
                k++;
                j++;
            }
            return C;
        }

    这个时间复杂度O(N+M)

    对于一个数组的时候,low - mid是有序的,mid+1--high是有序的,进行归并操作

        public void merge(int[] A,int low ,int mid ,int high){
            int len = high - low + 1;
            int[] C = new int[len]; // 只临时保存low - high大小的数组
            int i= low;
            int j = mid + 1;
            int k = 0;
            while(i <= mid && j<=high){
                if(A[i] <= A[j]){
                    C[k] = A[i];
                    k++;
                    i++;
                }else{
                    C[k] = A[j];
                    k++;
                    j++;
                }
            }
            while(i<= mid){
                C[k] = A[i];
                k++;
                i++;
            }
            while(j<= high){
                C[k] = A[j];
                k++;
                j++;
            }
            for(i = 0;i<len;i++){
                A[i + low] = C[i]; // 更新A
            }
    
        } 

    归并排序工作原理:(假设序列共有n个元素): 

    1.将序列每相邻两个数字进行归并操作(merge),形成floor(n/2)个序列,排序后每个序列包含两个元素 

    2.将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素 

    3.重复步骤2,直到所有元素排序完毕

        public void mergeSort(int[]A,int low,int high){
            if(low>=high)
                return;
            int mid = low + (high - low)/2;
            mergeSort(A,low,mid);// 左侧排序
            mergeSort(A,mid+1,high); // 右侧排序
            merge(A,low,mid,high); // 归并
        }

    俨然的一种后序遍历的感觉

    左侧排序了

    右侧排序了

    合并了排序数组

    空间复杂度:O(N)

    时间复杂度:O(NlogN)

  • 相关阅读:
    什么是子网掩码?(转)
    测试LM414-IOT网关MQTT功能
    连接s7-200时,提示未找到指定的访问点
    github中文件夹后面跟@+数字什么意思?为什么git clone下来里面是空的?
    Java知识32 数据结构 枚举 向量【多测师】
    java知识31 void 、实例化对象后面带参数、 实例变量(重点)【多测师】
    Java知识30 package【多测师】
    Java知识29 接口【多测师】
    java知识28 Java封装【多测师】
    Java知识27 抽象类【多测师】
  • 原文地址:https://www.cnblogs.com/bbbblog/p/5613579.html
Copyright © 2011-2022 走看看