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)

  • 相关阅读:
    Elasticsearch 入门教程
    Spring Boot集成JasperReports生成PDF文档
    Java程序员须知的七个日志管理工具
    vue 2 使用Bus.js进行兄弟(非父子)组件通信 简单案例
    spring boot项目在外部tomcat环境下部署
    linux 如何正确的关闭mongodb
    Centos7下yum安装配置nginx与php
    Centos7 搭建lnmp环境 (centos7+nginx+MySQL5.7.9+PHP7)
    CentOS7安装MySQL
    搭建MySQL高可用负载均衡集群(转)
  • 原文地址:https://www.cnblogs.com/bbbblog/p/5613579.html
Copyright © 2011-2022 走看看