归并排序【Java实现】
2016-12-17 16:22
381 查看
归并排序(Merge Sort)
基本思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
归并排序示例:
合并方法:
设r[i…n]由两个有序子表r[i…m]和r[m+1…n]组成,两个子表长度分别为n-i +1、n-m。
j=m+1;k=i;i=i; //置两个子表的起始下标及辅助数组的起始下标
若i>m 或j>n,转⑷ //其中一个子表已合并完,比较选取结束
//选取r[i]和r[j]较小的存入辅助数组rf
如果r[i]<r[j],rf[k]=r[i]; i++; k++; 转⑵
否则,rf[k]=r[j]; j++; k++; 转⑵
//将尚未处理完的子表中元素存入rf
如果i<=m,将r[i…m]存入rf[k…n] //前一子表非空
如果j<=n , 将r[j…n] 存入rf[k…n] //后一子表非空
合并结束。
/* * 两个有序子列的归并,两个子列的长度都相等,为length * 两个有序子列归并后,存入在数组temp中 */ public static void merge(int[] a,int[] temp,int length,int l,int r){ int begin = l; int leftend = r -1; int rightend = r+length-1; while(l<=leftend && r<=rightend){ if(a[l] > a[r]){ temp[begin++] = a[r++]; }else{ temp[begin++] = a[l++]; } } while(r<=rightend){ temp[begin++] = a[r++]; } while(l<=leftend){ temp[begin++] = a[l++]; } }
一个无序的序列可以采用分而治之的思想:
(1)从长度为1的子序列开始归并,则变成了都是长度为2的有序子序列;
(2)按长度为2的子序列开始归并,则变成了都是长度为4的有序子序列;
(3)。。。。
(4)归并结束。
序列归并的非递归算法
/*
* 6、归并排序
* 非递归归并实现
* 把一个序列,从0下标开始,先对1对数进行归并,然后再对2对数进行归并。。。
*/
public static void merge_sort(int[] a,int n){
int length = 1;//归并子序列的长度
int[] temp = new int
;
while(length<n){
merge_pass(a, temp, n, length);
length *= 2;
merge_pass(temp, a, n, length);
length *= 2;
}
}
/*
* 完成一躺子序列归并
* length为归并子序列的长度
*/
public static void merge_pass(int[] a,int[] temp,int n,int length){
int i = 0;
for (; i <= n-2*length; i=2*length+i) {
merge(a, temp, length, i, i+length);
}
if(i+length<n){//最后还剩下大于等于一个子列长度
merge(a, temp, n-i-length, i, i+length);
}else{//最后只剩下小于一个子列长度,则直接赋值
for (int j = i; j < n; j++) {
temp[j] = a[j];
}
}
System.out.print("子列长为"+length+"归并: ");
display(temp);
}
/* * 两个有序子列的归并,两个子列的长度都相等,为length * 两个有序子列归并后,存入在数组temp中 */ public static void merge(int[] a,int[] temp,int length,int l,int r){ int begin = l; int leftend = r -1; int rightend = r+length-1; while(l<=leftend && r<=rightend){ if(a[l] > a[r]){ temp[begin++] = a[r++]; }else{ temp[begin++] = a[l++]; } } while(r<=rightend){ temp[begin++] = a[r++]; } while(l<=leftend){ temp[begin++] = a[l++]; } }
测试代码:
public static void main(String[] args) { int[] a = {3,2,4,6,11,3,34,27,2,1,22,9,45,6}; int[] temp = new int[a.length]; System.out.print("子序列归并之前: "); display(a); merge_sort(a, a.length); }
结果为:
子序列归并之前: 3 2 4 6 11 3 34 27 2 1 22 9 45 6
子列长为1归并: 2 3 4 6 3 11 27 34 1 2 9 22 6 45
子列长为2归并: 2 3 4 6 3 11 27 34 1 2 9 22 6 45
子列长为4归并: 2 3 3 4 6 11 27 34 1 2 6 9 22 45
子列长为8归并: 1 2 2 3 3 4 6 6 9 11 22 27 34 45
相关文章推荐
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- java(Merge) 实现归并排序,快速排序
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 归并排序的java实现
- 用Java实现归并排序(Merge-Sort)算法
- 归并排序Java实现
- -------归并排序,基数排序(java实现)
- 程序员必知的8大排序(四)-------归并排序,基数排序(java实现)
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 归并排序Java实现
- 【转】排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 程序员必知的8大排序(四)-------归并排序,基数排序(java实现)
- Java实现快速排序、归并排序、堆排序
- 排序算法复习(Java实现):插入,冒泡,选择,Shell,快速排序, 归并排序,堆排序,桶式排序,基数排序
- 【转】排序算法复习(Java实现) (二): 归并排序,堆排序,桶式排序,基数排序
- 归并排序(java实现)
- 归并排序(java实现)
- Java实现归并排序