• 算法笔记_014:合并排序(Java)


    1 问题描述

    给定一组数据,使用合并排序得到这组数据的非降序排列。


    2 解决方案

    2.1 合并排序原理简介

    引用自百度百科:

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

    合并排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

    将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。合并排序也叫归并排序

         下面看一下具体排序示例:

     

    排序性能分析:

     

    2.2 具体编码

    package com.liuzhen.chapterFive;
    
    public class Mergesort {
        //使用合并排序,获取数组A的非降序排列
        public static void getMergesort(int[] A){
            int lenA = A.length;      //数组A的长度
            if(lenA > 1){
                int[] B = copyArray(A,0);   //获取数组A中前一半元素
                int[] C = copyArray(A,1);   //获取数组A中后一半元素
                getMergesort(B);            //递归排序B中元素
                getMergesort(C);            //递归排序C中元素
                Merge(B,C,A);               //合并数组B和C,返回A的非降序序列
            }
        }
        
        //返回数组A前一半或者后一半的元素,参数a用于判定前一半或者后一半元素
        public static int[] copyArray(int[] A,int a){
            int[] result;
            int len = A.length;
            if(a == 0){         //当a为0时代表返回数组A的前一半元素
                result = new int[len/2];
                for(int i = 0;i < len/2;i++)
                    result[i] = A[i];
            }
            else{              //a不为0时代表返回数组A的后一半元素
                result = new int[len-len/2];
                for(int i = 0;i < (len-len/2);i++)
                    result[i] = A[len/2+i];
            }
            return result;
        }
        
        //合并数组B和C,并将其变成非降序序列存入数组A中
        public static void Merge(int[] B,int[] C,int[] A){
            int i = 0,j = 0,k = 0;
            int lenB = B.length;  //数组B的长度
            int lenC = C.length;  //数组C的长度
            while(i<lenB && j<lenC){
                if(B[i] < C[j]){       
                    A[k] = B[i];    
                    i++;
                }
                else{
                    A[k] = C[j];
                    j++;
                }
                k++;
            }
            if(i == lenB){ //当i等于lenB时,说明B数组中数已经全部存入A中,再把C数组中剩下的元素直接存入数组A中即可
                while(j<lenC){
                    A[k] = C[j];
                    j++;
                    k++;
                }
            }
            if(j == lenC){ //当j等于lenC时,说明C数组中数已经全部存入A中,再把B数组中剩下的元素直接存入数组A中即可
                while(i<lenB){
                    A[k] = B[i];
                    i++;
                    k++;
                }
            }
        }
        
        public static void main(String[] args){
            int[] A = {8,3,2,9,7,1,5,4,4,45,3,2,22};
            getMergesort(A);
            System.out.println("使用合并排序获得A数组的非降序序列结果如下:");
            for(int i = 0;i < A.length;i++)
                System.out.print(A[i]+"	");
            
        }
    }

    运行结果:

    使用合并排序获得A数组的非降序序列结果如下:
    1    2    2    3    3    4    4    5    7    8    9    22    45    
  • 相关阅读:
    [转]进程的用户栈和内核栈
    什么是URL,URL格式
    设计灵感
    Spring源码学习相关记录
    HTML图片标签路径解析
    一次Spring Bean初始化顺序问题排查记录
    是要面向对象,还是简单粗暴?
    2018/07/26学习节点记录
    数据结构-堆 Java实现
    2018 ICPC 徐州邀请赛 总结
  • 原文地址:https://www.cnblogs.com/liuzhen1995/p/6272767.html
Copyright © 2020-2023  润新知