zoukankan      html  css  js  c++  java
  • 归并排序:步骤讲解与代码实现

    归并排序 

      在一些常用的排序中,归并排序在时间开销上来说可以是排序中的最佳实践之一(时间复杂度=n*log n),今天我们就来看看归并是如何实现的。

      归并排序大致可以分为两步:

        1、将数组从中间分开,对两边分别排序。

        2、将两个有序的数组进行合并。

      所以实现归并排序主要也就是解决这两个问题。

      下图是归并排序的大致步骤,红线代表将数组拆开,蓝箭头代表将拆后的数组分别处理,红箭头代表将数组排序后返回

     

    问题1:如何将数组分开,并进行分别排序?

    答:使用递归实现

    问题2:如何将两个有序的数组进行合并排序?

    假设如上图的第二行中,需要合并(2,4,5,8)和(1,3,6,7)两个数组。

    1,因为这两个数组都是增序的,只需要比较俩个数组的第一个数,那么比较小的数必然是两数组中最小的数

      例:比较(2,4,5,8)的2 和(1,3,6,7)的1,那么1必然是两数组中最小的数。

    2,将这个数放入一个新的数组。

      例:将1放入数组a[]中,两数组还有(2,4,5,8)的2 和(3,6,7)

    3,再次重复第1步。

    .....

    如此比较直到其中一个数组结束,将另一个数组剩下的值全部放入数组a

     那么数组a便是排好序的数组。

    代码实现:

    public class MergesSort {
        //排序函数,target为要排序的数组,
           // begin和end为要排序的区间的开始和结束坐标
        public void mergeSort(int target[],int begin,int end){
            //当要排序的数组区间只有一个数时直接返回
            if((end-begin)==0){
                return ;
            }
            //当排序的数组区间有两个数时,对这两个数进行比较
            if((end-begin==1)){
                sortS2B(target,begin,end);
                return ;
            }
            //当要排序的数组大于2个时,我们就分割此数组的区间,分别排序;
            int mid=(begin+end)/2;
            mergeSort(target,begin,mid);
            mergeSort(target,mid+1,end);
            
            //将排序好的俩数组的区间进行合并排序
            
            //创建一个数组用于存放排好序的数组,大小就是区间大小
            int temp[]=new int[end-begin+1];
            //存放第一个数组的开始坐标
            int p1=begin;
            //存放第二个数组的开始坐标
            int p2=mid+1;
            //存放temp数组最近一次存放的数的坐标,初始为0
            int p3=0;
          
    while(p1<=mid&&p2<=end){ //将小的数存到temp数组 if(target[p1]<target[p2]){ temp[p3]=target[p1]; p3++; p1++; }else{ temp[p3]=target[p2]; p3++; p2++; } } //检查是否还有没有插入的 while(p1<=mid){ temp[p3]=target[p1]; p3++; p1++; } while(p2<=end){ temp[p3]=target[p2]; p3++; p2++; } //将排好的数组temp与原target的替换 System.arraycopy(temp, 0, target, begin, temp.length); }
    //将数组target的a和b坐标的两个数按small to big从小到大排序 public void sortS2B(int target[],int begin,int end){ //如果begin>end,进行交换 if(target[begin]>target[end]){ int temp=target[begin]; target[begin]=target[end]; target[end]=temp; } return ; } public static void main(String[] args) { MergesSort ms=new MergesSort(); int a[]={8,-6,2,-7,9,-23,2,7,4,67,1,8}; //注意第三个参数是数组的结束坐标,应该因为数组是从0开始的,所以结束的坐标需要数组的长度-1 ms.mergeSort(a,0,a.length-1); int i=0; while(i<a.length){ System.out.print(a[i++]+" "); } } }

    代码测试:

        //测试代码
            public static void main(String[] args) {
            MergesSort ms=new MergesSort();
            
            int a[]={8,-6,2,-7,9,-23,2,7,4,67,1,8};
            //注意第三个参数是数组的结束坐标,因为数组是从0开始的,所以结束的坐标需要数组的长度-1
            ms.mergeSort(a,0,a.length-1);
            int i=0;
            while(i<a.length){
                System.out.print(a[i++]+"  ");
            }
        }

    结果:

    写此博客希望以后忘记的时候能够回顾一下,代码如果有不对的地方,请大佬们指正,谢谢~

  • 相关阅读:
    WebLogic10 & MyEclipse 配置(转)
    java中的接口隔离(ISP)
    java多线程之 wait(),notify(),notifyAll()
    Windows Server 2008 R2终端服务器激活方法
    [zt]PHP+jQuery+Ajax实现用户登录与退出
    USACO Window AreaDFS矩形切割
    eWebEditor在IE8,IE7下所有按钮无效之解决办法
    [zt]【HoorayOS】开源的Web桌面应用框架——安装部署
    javascript Date format(js日期格式化)
    web design
  • 原文地址:https://www.cnblogs.com/chenkeyu/p/7501169.html
Copyright © 2011-2022 走看看