package ls.algorithm.sort; public class MergeSort extends SortInf { int[] temp; public MergeSort(int size) { //这里在抽象内中随机生成了一个数组,并打印显示 super(size); this.printSrcArr();// temp=new int[size]; copyArr(arr,temp); // TODO Auto-generated constructor stub } private void copyArr(int[] src,int[] target) { if(src.length!=target.length) { System.out.println("长度不一致数组无法复制"); return ; } for(int i=0;i<src.length;i++) { target[i]=src[i]; } } @Override public void sort() { // TODO Auto-generated method stub int gap=1; //当步长大于或等于数组长度时,表示上一次已经合并了数组所有元素 while(gap<(2*arr.length)) { //按照gap长度对数组进行遍历,分组合并 for(int i=0;i<arr.length;i=i+2*gap)//因为合并单个数字长为gap,因此循环的步长为2*gap { mergeArr(i,gap); } //每次合并,gap步长是上一次的2倍 gap=gap*2; } this.printSrcArr(); } private void mergeArr(int start,int gap) { if(start+gap>=arr.length) { //后面已没有多余数组,不需要在合并 return ; } //合并相邻的数组 int leftStart=start;//左边数组起点位置 int leftEnd=start+gap-1;//左边数组尾部位置 int rightStart=start+gap;//右边数组起点位置 int rightEnd=start+gap+gap-1;//右边数组尾部位置 //如果右边数组的边界小于源数组边界,则不处理;否则右边数组边界则等于源数组右边边界 rightEnd=rightEnd<=arr.length-1?rightEnd:arr.length-1; //正式合并相邻数组,并将数据存储到同等大小的临时数组; for(int n=leftStart;n<=rightEnd;n++) { if(leftStart>leftEnd) //如果左边已经读完了。将右边剩下的依次放入临时序列 { temp[n]=arr[rightStart]; rightStart++; continue; } if(rightStart>rightEnd) //如果右边已经读完了。将左边剩下的依次放入临时序列 { temp[n]=arr[leftStart]; leftStart++; continue; } if(leftStart<=leftEnd&&rightStart<=rightEnd)//如果两边都没有读完,继续比较 { if(arr[leftStart]<=arr[rightStart]) { temp[n]=arr[leftStart]; leftStart++; } else { temp[n]=arr[rightStart]; rightStart++; } } } copyArr(temp,arr); //将当前序列复制给原始序列 // this.printSrcArr(); //打印当前合并后的数组 } }
//下面是随机生成需排序数组的抽象类。
package ls.algorithm.sort; import java.util.Random; public abstract class SortInf { int[] arr; public SortInf(int size) { arr=new int[size]; for(int i=0;i<size;i++) { arr[i]=new Random().nextInt(50); } } public void printSrcArr() { System.out.print("数组:"); for(int i=0;i<arr.length;i++) { System.out.print(arr[i]+" "); } System.out.print("\n"); } public abstract void sort(); }