在一些经常使用的排序中,归并排序在时间开销上来讲能够是排序中的最佳实践之一(时间复杂度=n*log n),今天咱们就来看看归并是如何实现的。数组
归并排序大体能够分为两步:函数
一、将数组从中间分开,对两边分别排序。测试
二、将两个有序的数组进行合并。spa
因此实现归并排序主要也就是解决这两个问题。code
下图是归并排序的大体步骤,红线表明将数组拆开,蓝箭头表明将拆后的数组分别处理,红箭头表明将数组排序后返回blog
问题1:如何将数组分开,并进行分别排序?排序
答:使用递归实现递归
问题2:如何将两个有序的数组进行合并排序?get
假设如上图的第二行中,须要合并(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++]+" "); } }
结果:
写此博客但愿之后忘记的时候可以回顾一下,代码若是有不对的地方,请大佬们指正,谢谢~