归并排序其实就是将一个数组分成左右两部分,先排序左边的部分,再排序右边的部分,最后将两部分整合再一起。而左边又可以继续下分左边和右边,右边也可以分为左边和右边,就是一个递归的过程
下面是例子:
例如:
数组a[6],如图所示:
定义变量L=0(数组左边的下标),R=a.length-1(数组右边的下标),Mid=(L+R)/2(数组中间部分的下标)
左边部分
进行排序
右边部分
左边部分进行排序以后:
右边进行排序以后:
重点来了,归并在一起:
先定义两个辅助下标p1,p2,辅助数组help;
循环往复,就可以实现归并,当然递归依次下来也是这样
下面是代码:
import java.util.Scanner;
public class guibing {//归并排序
public static void main(String[] args) {
int[] a = new int[6];
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < a.length; i++){
a[i] = scanner.nextInt();//输入你要排序的序列
}
guibing(a);//归并排序
for (int i=0;i<a.length;i++){
System.out.print(a[i]+" ");//输出排序后的数组
}
}
public static void guibing(int[] a){
int L = 0;
int R = a.length-1;
process(a,L,R);
}
public static void process(int[] a,int L,int R){
if(L==R){//当L=R的时候,结束递归
return;
}
int Mid = L + ((R-L)>>1);//Mid = (L+R)/2,防止数组过长的时候L+R越界,(R-L)>>1向右位移动一位,即除以2
process(a,L,Mid);//对左边的进行排序
process(a,Mid+1,R);//对右边进行排序
merge(a,L,R,Mid);//将两边序列进行整合
}
public static int[] merge(int[] a,int L,int R,int M){
int help[] = new int[R-L+1];//创建一个辅助数组,用于临时存储左右序列经过排序以后的序列
int p1 = L;//a[L]~a[M]
int p2 = M+1;//a[M+1]~a[R]
int i = 0;
while (p1<=M&&p2<=R){
help[i++] = a[p1]<a[p2] ? a[p1++]:a[p2++];
}
while (p1<=M){
help[i++] = a[p1++];
}
while (p2<=R){
help[i++] = a[p2++];
}
//两个while只有一个while会执行
for (int j=0;j<help.length;j++){
a[L+j] = help[j];//将辅助序列导入到数组a[L]~a[R]中
}
return a;
}
}
时间复杂度为T(N)=2(N/2)+O(N)(master公式)
由master公式可得时间复杂度为:T(N) = T(N)=2(N/2)+O(N),当log(b,a)=d时,时间复杂度为O(N*logN),额外空间复杂度为O(N)