合并排序
利用分治策略入手,将需要排序的序列集合一划分为二,又将其划分好的两个子集划分为两个小子集,直至只剩一个元素为止。然后不断合并两个排好序的数据段,有少到多重复下去,直至整个序列排好序。
package helloy;
import java.util.Arrays;
public class qSort {
/*以[8,4,3,7,5,1,6,2]为例
[4, 8, 0, 0, 0, 0, 0, 0]
[4, 8, 3, 7, 0, 0, 0, 0]
[4, 8, 3, 7, 1, 5, 0, 0]
[4, 8, 3, 7, 1, 5, 2, 6]
[3, 4, 7, 8, 5, 1, 6, 2]
[3, 4, 7, 8, 1, 2, 5, 6]
[1, 2, 3, 4, 5, 6, 7, 8]
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[]=new int[] {8,4,3,7,5,1,6,2};
mergeSort(a);
System.out.println(Arrays.toString(a));
}
//排好序的数组进行合并
public static void mergeSort(int a[]) {
int b[]=new int[a.length];
int s=1;
while(s<a.length) {
//合并到数组b
mergePass(a,b,s);
s+=s;
//合并(复制)到数组a中
mergePass(b,a,s);
s+=s;
}
}
public static void mergePass(int x[],int y[],int s) {
//合并大小为s的相邻子数组
int i=0;
//合并大小为s的相邻两段
//可举例 若长度为10个元素,s为2,则i<6
/*(0,1,3)
(4,5,7)
(8,9,11)(i为8跳出进入下面的语句)*/
while(i<x.length-2*s) {
merge(x,y,i,i+s-1,i+2*s-1);
//确定下一次起点下标
i=i+2*s;
}
//剩余元素个数大于s小于2s
if(i+s<x.length)
merge(x,y,i,i+s-1,x.length-1);
//剩余元素个数小于等于s
else
for(int j=i;j<x.length;j++) {
y[j]=x[j];
}
}
//合并
public static void merge(int c[],int d[],int l,int m,int r) {
//合并c[1:m]和c[m+1:r]到d[1:r]
int i=l,j=m+1,k=l;
//以m为划分线,前后进行比较,较小的放进新数组d中
while((i<=m)&&(j<=r)) {
if(c[i]<=c[j]) d[k++]=c[i++];
else d[k++]=c[j++];
}
//若前后两部行比较完后有剩余的元素,再进行处理
//后子段还有元素,将其放进数组d中
if(i>m)
for(int q=j;q<=r;q++)
d[k++]=c[q];
//前子段有元素,将其放进数组d中
else
for(int q=i;q<=m;q++)
d[k++]=c[q];
}
}
如有不足,请多包涵。