将两个的有序数列合并成一个有序数列,我们称之为”归并”。
归并排序:
将待排序的数列分成若干个长度为1的子数列,然后将这些数列两两合并;得到若干个长度为2的有序数列,再将这些数列两两合并;得到若干个长度为4的有序数列,再将它们两两合并;直接合并成一个数列为止。这样就得到了我们想要的排序结果。
/*俩俩归并子序列
*/
public static void merge(int []a,int length){//length代表的是子序列的长度
int s1=0;//指向第一个子序列的第一个元素
int e1=s1+length-1;//指向第一个子序列的最后一个元素
int s2=e1+1;//指向第二个子序列的第一个元素
int e2=s2+length-1<a.length?s2+length-1:a.length-1;//指向第二个子序列的最后一个元素
int []b=new int[a.length];//得到一个与原数组长度相同的数组,以便于在排序过程中储存子序列
int i=0;//b数组的下标
while(s2<a.length){//s2循环到第二个子序列最后
while(s1<=e1&&s2<=e2){//当s1 s2指向的位置都存在元素的时候
if(a[s1]<a[s2]){//把s1 s2所对应元素中小的元素给b数组
b[i]=a[s1];
i++;//指针移动
s1++;
}
else{
b[i]=a[s2];
i++;//指针移动
s2++;
}
}
while(s1<=e1){//当第二个子序列走完,但是第一个子序列还有元素的时候
b[i]=a[s1];//把第一个子序列的剩下的值给b数组
i++;//指针移动
s1++;
}
while(s2<=e2){//当第一个子序列走完,但是第二个子序列还有元素的时候
b[i]=a[s2];//把第二个子序列的剩下的值给b数组
i++;//指针移动
s2++;
}
s1=e2+1;//让所有的指针指向下俩个相邻子序列的开头与结尾
e1=s1+length-1;
s2=e1+1;
e2=s2+length-1<a.length?s2+length-1:a.length-1;
}
while(s1<a.length){//如果一开始第二个子序列中就没有元素
//直接把第一个子序列中的元素给b数组
b[i]=a[s1];
i++;//指针移动
s1++;
}
for(int j=0;j<b.length;j++){//把排序后的数组元素给原来的数组
a[j]=b[j];
}
}
/*归并排序
*/
public static void mergesort (int []a){
for(int i=1;i<a.length;i=i*2){
merge(a,i);
}
}
测试代码
public static void main(String[] args) {
int []a={5,6,8,3,4,2,1,7};
mergesort(a);
System.out.println(Arrays.toString(a));
// TODO Auto-generated method stub
}
结果:
[1, 2, 3, 4, 5, 6, 7, 8]