归并排序 - 递归非递归实现java

Posted leechee9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了归并排序 - 递归非递归实现java相关的知识,希望对你有一定的参考价值。

1.归并排序思想:

以2路归并为例,一个有n个记录的序列可以看作n个长度为1的有序子序列,将其两两合并成n/2(向上取整)个长度为2或1的有序序列,当有奇数个记录时为1,重复归并,直到得到一个长度为n的有序序列。

2.归并排序的复杂度:

递归:时间复杂度O(nlongn),空间复杂度O(n+longn)

非递归:时间复杂度O(nlongn),空间复杂度O(n)

所以用到归并排序,还是优先考虑非递归吧。

 3.递归实现

 1     public void mergeSort1(int[] data){
 2         msort(data,0,data.length-1);
 3     }
 4 
 5     public void msort(int[] data, int start, int end){
 6         if(start < end){
 7             int mid = (start + end) >>> 1;
 8             msort(data,start,mid);
 9             msort(data,mid+1,end); //当mid+1 == end时,子序列长度为1,退出msort,进入merge()排序
10             merge(data,start,mid,end);
11         }
12     }
13 
14     public void merge(int[] data, int start, int mid, int end){
15         int s1 = start;     //子序列1在data[]的起始下标
16         int s2 = mid + 1;  //子序列2在data[]的起始下标
17         int[] tmp = new int[end - start +1];
18         int index = 0; //临时数组tmp的下标
19         while((s1 <= mid) && (s2 <= end)){ //两个序列都还没有完全放入tmp[]中
20             if(data[s1] < data[s2]) tmp[index++] = data[s1++];
21             else tmp[index++] = data[s2++];
22         }
23         while(s1 <= mid){ //第2个序列已经完全放入tmp中,由于s1本身是有序的,将s1剩下的元素直接放入
24             tmp[index++] = data[s1++];
25         }
26         while(s2 <= end){
27             tmp[index++] = data[s2++];
28         }
29         for(int i = 0; i < tmp.length; i++){
30             data[start++] = tmp[i];
31         }
32     }

 

4.非递归实现

 1    public void mergeSort2(int[] data){
 2         int k = 1;  //k是子序列的长度,二路归并每次处理两个子序列,所以k< data.length
3 while(k < data.length){ 4 merge(data,k); 5 k *= 2; 6 } 7 } 8 9 public void merge(int[] data, int len){ 10 int s1 = 0; 11 int e1 = s1+len-1; 12 int s2 = e1+1; 13 int e2 = s2+len-1 < data.length ? s2+len-1 : data.length-1; 14 int[] tmp = new int[data.length]; 15 int index = 0; 16 while(s2 < data.length){ //第一种情况存在两个序列 17 while((s1 <= e1) && (s2 <= e2)){ 18 if(data[s1] < data[s2]) tmp[index++] = data[s1++]; 19 else tmp[index++] = data[s2++]; 20 } 21 while(s1 <= e1){ 22 tmp[index++] = data[s1++]; 23 } 24 while(s2 <= e2){ 25 tmp[index++] = data[s2++]; 26 } 27 s1 = e2 + 1; //处理下一组的两个子序列 28 e1 = s1 + len -1; 29 s2 = e1 + 1; 30 e2 = s2 + len - 1 < data.length ? s2 + len -1 : data.length -1; 31 } 32 while(s1 < data.length){ //第二种情况,只剩下一个子序列了 33 tmp[index++] = data[s1++]; 34 } 35 for(int i = 0; i < data.length; i++){ 36 data[i] = tmp[i]; 37 } 38 }

 

以上是关于归并排序 - 递归非递归实现java的主要内容,如果未能解决你的问题,请参考以下文章

归并排序(非递归,Java实现)

[ 数据结构 -- 手撕排序算法第六篇 ] 归并排序(下)-- 非递归方法实现

排序3-选择排序与归并排序(递归实现+非递归实现)

javascript实现非递归--归并排序

归并排序详解(MergeSort)递归和非递归实现

重温基础算法内部排序之归并排序法