版权声明:中华人民共和国持有版权 https://blog.csdn.net/Fly_Fly_Zhang/article/details/86163425
思路:归并排序是建立在归并操作上的一种有效的排序算法,是采用分治法的一个典型应用; 即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
首先考虑如何将两个有序数组合并,这个只需要比较两个数组的s谁小先将谁放入新数组,直到是走到末尾;
class TestMergeSort{
/*
* @Description :
* @param array
* @param gap :每个归并段的数据个数
* @return : void
* @exception :
* @date : 2019/1/9 15:59
*/
public static void merge(int [] array,int gap){
int [] tmpArr=new int [array.length]; //空间复杂度O(n)
int i=0;
int s1=0;
int e1=s1+gap-1;
int s2=e1+1; //因为gap长度最大到 array.length-1 ,
// 所以e1最大是array.length-2;s2最大是array.length-1, 因此e1 不回越界;
int e2=s2+gap-1 > array.length-1 ? array.length-1 : s2+gap-1;
while(s2<array.length){ //肯定有两个归并段,只不过第二个归并段可能只有一个数据
while(s1<=e1 && s2<=e2){ //当两个归并段都有数据时;
if(array[s1]<array[s2]){
tmpArr[i++]=array[s1++];
}else{
tmpArr[i++]=array[s2++];
}
}
while(s1<=e1){
tmpArr[i++]=array[s1++];
}
while(s2<=e2){
tmpArr[i++]=array[s2++];
}
//确定新的坐标 如果s2已经超出坐标,那就会跳出循环;
s1=e2+1;
e1=s1+gap-1;
s2=e1+1;
e2=s2+gap-1 > array.length-1 ? array.length-1 : s2+gap-1;
}
while(s1<array.length){ //跳出上一个循环后,s1可能
tmpArr[i++]=array[s1++];
}
System.arraycopy(tmpArr,0,array,0,array.length);
}
public static void mergeSort(int [] array){
for (int i = 1; i <array.length ; i*=2) {
merge(array,i);
}
}
public static void main(String [] args){
int array []=new int[10000];
Random random=new Random();
for(int i=0;i<array.length;i++){
array[i]=random.nextInt(10000)+1;
}
mergeSort(array);
System.out.println(Arrays.toString(array));
}
}