标题:Java排序算法之归并排序
一、思想
- 将n个记录看成是n个长度为1的有序子表组成
- 将两两相临的子表归并一个有序子表
二、解题过程
第一步:
* 将a[]看成是两个子表,
* 一个起点为start1 ,长度为len1
* 一个起点为start2 ,长度为len2
* 对两个子表进行排序【利用两个子表已排好序的特性】
/**
*将a[]看成是两个子表,
*一个起点为start1 ,长度为len1
*一个起点为start2 ,长度为len2
*对两个子表进行排序【利用两个子表已排好序的特性】
* @param a
* @param start1
* @param len1
* @param start2
* @param len2
* @return
*/
public int[] mergesort(int[] a,int start1,int len1,int start2,int len2) {
int i=start1;
int j=start2;
int[] nums=new int[a.length];
int t=0;
while(i<(start1+len1) && j<(start2+len2)) {
if(a[i]<=a[j]) {
nums[t++]=a[i];
i++;
}else {
nums[t++]=a[j];
j++;
}
}
while(i<(start1+len1)) {
nums[t++]=a[i++];
}
while(j<(start2+len2)) {
nums[t++]=a[j++];
}
for(int p=0;p<t;p++) {
a[p+start1]=nums[p];
}
// for(int in:a) {
// System.out.print(in+" ");
// }
// System.out.println(" ");
return a;
}
第二步:
* 调用上述的排序,
* 第一个for循环,控制子表的长度
* 第二个for循环,控制子表的数量
* 每次的两个子表,长度不一定相等
* 注意特例:1)长度为1时,* * *【单独出来的】,两两配对 -->最后面的一个*放置,等待下一次调用
* 2)长度为2时,{*,*} *【此处长度小于len】两两配对 -->调用mergesor时,传入 的长度为2,1
/**
* 调用上述的排序,
* 第一个for循环,控制子表的长度
* 第二个for循环,控制子表的数量
* 每次的两个子表,长度不一定相等
* 注意特例:1)长度为1时,* * *【单独出来的】,两两配对 -->最后面的一个*放置,等待下一次调用
* 2)长度为2时,{*,*} *【此处长度小于len】两两配对 -->调用mergesor时,传入 的长度为2,1
* @param a
* @return
*/
public int[] merge(int[] a) {
for(int len=1;len<a.length;len*=2) {
int sum=a.length;
for(int j=0;j<a.length;) {
int len1=len;
int len2=len;
if(sum-len>0) {
sum-=len;
}else break;
if(sum-len>=0) {
sum-=len;
}else {
len2=sum;
}
a=this.mergesort(a, j, len1, j+len1, len2);
j=j+len1+len2;
}
}
return a;
}
完整代码:
/**
* 测试归并排序
* 将n个记录看成是n个长度为1的有序子表组成
* 将两两相临的子表归并一个有序子表
* 重复上述步骤
* @author dell
*
*/
public class MergeSort {
/**
*将a[]看成是两个子表,
*一个起点为start1 ,长度为len1
*一个起点为start2 ,长度为len2
*对两个子表进行排序【利用两个子表已排好序的特性】
* @param a
* @param start1
* @param len1
* @param start2
* @param len2
* @return
*/
public int[] mergesort(int[] a,int start1,int len1,int start2,int len2) {
int i=start1;
int j=start2;
int[] nums=new int[a.length];
int t=0;
while(i<(start1+len1) && j<(start2+len2)) {
if(a[i]<=a[j]) {
nums[t++]=a[i];
i++;
}else {
nums[t++]=a[j];
j++;
}
}
while(i<(start1+len1)) {
nums[t++]=a[i++];
}
while(j<(start2+len2)) {
nums[t++]=a[j++];
}
for(int p=0;p<t;p++) {
a[p+start1]=nums[p];
}
// for(int in:a) {
// System.out.print(in+" ");
// }
// System.out.println(" ");
return a;
}
/**
* 调用上述的排序,
* 第一个for循环,控制子表的长度
* 第二个for循环,控制子表的数量
* 每次的两个子表,长度不一定相等
* 注意特例:1)长度为1时,* * *【单独出来的】,两两配对 -->最后面的一个*放置,等待下一次调用
* 2)长度为2时,{*,*} *【此处长度小于len】两两配对 -->调用mergesor时,传入 的长度为2,1
* @param a
* @return
*/
public int[] merge(int[] a) {
for(int len=1;len<a.length;len*=2) {
int sum=a.length;
for(int j=0;j<a.length;) {
int len1=len;
int len2=len;
if(sum-len>0) {
sum-=len;
}else break;
if(sum-len>=0) {
sum-=len;
}else {
len2=sum;
}
a=this.mergesort(a, j, len1, j+len1, len2);
j=j+len1+len2;
}
}
return a;
}
@Test
public void test() {
// int[] a=new int[] {35,15,6,48,19,21,27};
// int[] a=new int[] {26,5,77,1,61,11,59,15};
// int[] a=new int[] {35,22,8,16,21,22,27};
// int[] a=new int[] {32,42,7,48,15,48,12,18};
// int[] a=new int[] {7,4,9,18,2,6,10};
int[] a=new int[] {26,57,24,2,1,68,5,34,588,9,25,647};
a = this.merge(a);
for(int in:a) {
System.out.print(in+" ");
}
}
@Test
public void test02() {
int[] a=new int[] {35,15,6,48,19,21,27};
this.mergesort(a, 0, 1, 1, 1);
}
}