归并排序的递归及非递归实现

 
  1 package DS;
  2 
  3 import java.util.Arrays;
  4 import java.util.Random;
  5 
  6 class MyMergeSort{
  7     //归并
  8     private void merge(int[] array, int start,int mid, int end,int[] tmpArray) {
  9      //   int[] tmpArray = new int[array.length];
 10         int tmpIndex = start;
 11         int i = start;
 12         int s2 = mid+1;
 13         //有俩个归并段
 14         while(start<=mid && s2<=end){
 15             //俩个归并段都从头开始比较
 16             // 小的拉到创建好的数组里
 17             //再将索引++;直到有一个归并段没数据,跳出循环
 18             if (array[start] <= array[s2]){
 19                 tmpArray[tmpIndex++] = array[start++];
 20             }else{
 21                 tmpArray[tmpIndex++] = array[s2++];
 22             }
 23         }
 24         //说明第一个归并段有数据
 25         while (start <= mid){
 26             tmpArray[tmpIndex++] = array[start++];
 27         }
 28         //第二个归并段有数据
 29         while (s2 <= end){
 30             tmpArray[tmpIndex++] = array[s2++];
 31         }
 32         //把排好序的数据从tmpArray拷贝array
 33         while (i<=end){
 34             array[i] = tmpArray[i];
 35             i++;
 36         }
 37     }
 38 
 39 //递归
 40     void mergeSort(int[] array, int start, int end,int[] tmpArray){
 41         if(start>=end){
 42             return;
 43         }
 44         int mid = (start+end)/2;
 45         mergeSort(array,start,mid,tmpArray);
 46         mergeSort(array,mid+1,end,tmpArray);
 47         merge(array,start,mid,end,tmpArray);
 48     }
 49     //非递归
 50     //归并
 51     public void merge2(int[] array,int gap){
 52         int[] tempArray = new int[array.length];
 53         int i = 0;//tempArray下标
 54         int start1 = 0;
 55         int end1 = start1+gap-1;
 56         int start2 = end1+1;
 57         int end2 = start2+gap-1<=array.length-1?start2+gap-1:array.length-1;
 58         //保证有俩个归并段
 59         while (start2 < array.length) {
 60             //保证俩个归并段都有数据
 61             while(start1<=end1 && start2<=end2){
 62                 //比较
 63                 if(array[start1]<array[start2]){
 64                    tempArray[i++] = array[start1++];
 65                 }else{
 66                     tempArray[i++] = array[start2++];
 67                 }
 68             }
 69             //退出循环是因为start2<=end2不成立,及说明start1~end1里还有未比较的数据
 70             while (start1 <= end1){
 71                 tempArray[i++] = array[start1++];
 72             }
 73             //退出循环是因为start1<=end1不成立,及说明start2~end2里还有未比较的数据
 74             while (start2<=end2){
 75                 tempArray[i++] = array[start2++];
 76             }
 77             //至此,及说明一次二路归并已走完,以下为修改指针,准备下一段归并
 78             start1 = end2 + 1;
 79             end1 = start1 + gap - 1;
 80             start2 = end1 + 1;
 81             end2 = start2+gap-1<=array.length-1?start2+gap-1:array.length-1;
 82         }
 83         //当start2,end2,甚至end1已经越界时,start1还有数据,且未处理,要把他作为未归并的
 84         //数据,拉到tempArray里
 85         while(start1 <array.length){
 86             tempArray[i++] = array[start1++];
 87         }
 88         //拷贝数据到原始数组
 89         //此处只能用for遍历去拷贝
 90         for(int j = 0;j<tempArray.length;j++){
 91             array[j] = tempArray[j];
 92         }
 93     }
 94     void mergeSort2(int[] array){
 95         for(int i = 1;i<array.length;i *= 2){
 96             merge2(array,i);
 97         }
 98     }
 99 }
100 
101 public class MergeSort {
102     public static void main(String[] args) {
103         MyMergeSort myMergeSort = new MyMergeSort();
104         int[] array = new int[10000];
105         Random random = new Random();
106         for(int i = 0;i<array.length;i++){
107             array[i] = random.nextInt(100000)+1;
108         }
109         int[] tmpArray = new int[array.length];
110         //myMergeSort.mergeSort(array,0,array.length-1,tmpArray);
111         myMergeSort.mergeSort2(array);
112         System.out.println(Arrays.toString(array));
113     }
114 }

猜你喜欢

转载自www.cnblogs.com/huanglu12138/p/11363172.html