归并排序:步骤讲解与代码实现

来源:互联网 发布:小米mix网络类型选择 编辑:程序博客网 时间:2024/06/03 14:18

归并排序 

  在一些常用的排序中,归并排序在时间开销上来说可以是排序中的最佳实践之一(时间复杂度=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++]+"  ");        }    }

结果:

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

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 2.编写一个C程序,假设图书馆的图书包含书名、编号和作者等3个属性,读者包含姓名和借书证属性,每位读 pythontcp实现聊天室 jstack RS编译码器 RS编译码器原理 高德地图 导航信息 当前导航路径信息 实时导航信息 高德导航时Navi的信息 高德NaviInfo 安卓蓝牙发送信息 clj.fastble 先采用队列求一条最短迷宫路径长度minlen,再采用栈求所有长度为minlen的最短迷宫路径 iOS蓝牙 pycharm激活 shadowsocks下载 shadowsocks下载 开源沙龙 C++程序设计从键盘中输入两个整数,求这两个整数的最大公约数和最小公倍数。 江南大学五部曲 centos搭建ss 算法之美_源代码发布(8) understand halfaSPIclockcycleproducesaclockedge 贪心算法活动 TRIZ系列-创新原理-17 朴素贝叶斯分类 王者荣耀金币 探索性数据分析演示 治安防控 治安 TRIZ系列-创新原理-19 TRIZ系列-创新原理-20 利用图像的平移、旋转、缩放、镜像等空间几何变换实现对图像的自适应缩放、几何变换等特效 利用图像的平移、旋转、缩放、镜像等空间几何变换实现对图像的几何变换等特效 [Err]1005-Can\'tcreatetable\'item4.#sql-1238_2c\'( SAPFICO财务成本知识 财务管理分析(希金斯:第八版) 图像解压 巜人民曰报》采访张文宏,陈尔真