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();
}