递归-归并排序 思想 JAVA实现

已知一个数组   1五、5八、6一、7五、21、32、89、4、78、83。采用递归实现的归并排序将数组有序。java

分治策略:(摘自《算法导论》)算法

在分治策略中,咱们采用递归解决问题数组

分解:将原问题分解为子问题,子问题与原问题同样,只不过规模更小。ui

解决:递归的求解子问题,若是子问题足够小,则中止递归,直接解决子问题。this

合并:将子问题的解组合为原问题的解。spa

归并的算法思想:blog

俩个已经有序的数组A,B合并为一个有序的数组C。排序

数组A:23,47,81,95 数组B:7,14,39,55,62,74递归

A[0]>B[0] ? C[0]=B[0] C[0]=A[0]; 内存

 以上即是归并的主要思想。

 

归并排序就是以这种思想为主加之递归的思想组成。即将已知的一个数组拆分为两个子数组,

在分别将俩个子数组再次分别拆分为俩个子数组,直到没法拆分为止,即子数组只有一个数组元素,而后对每一个子数组排序,使之成为有序子数组,而后将子数组合并。最后造成一个排序好的完整数组。

递归-归并排序的缺点

1:归并排序须要一个和原数组大小相等的数组辅助,进行数据的排序。消耗额外的内存。

2:递归是一种很好的解决问题的思路,可是递归因为须要保存“相关参数以及引用地址”,因此递归会有额外的内存开销。

因此综上,当数据量很是大的时候使用递归-归并排序就须要考虑“空间问题

归并排序是一个运行时间为NlgN的算法

如下是java实现递归-归并排序

public class GuiBingOrder {

          private int[] Array;

          private int currentIndex;

          private int maxIndex;

          public GuiBingOrder(int size) {
                    this.Array = new int[size];
                    this.currentIndex = 0;
                    this.maxIndex = size-1;
          }

          public void insert(int value) {
                  if(this.maxIndex<this.currentIndex) {
                      System.out.println("数组已满");
                  }else {
                      this.Array[this.currentIndex++] = value;
                  }
           }


           public void doOrder() {//开始排序
                 int[] orderArray = new int[this.currentIndex];  //须要额外开销的数组
                 this.GuiBinOrder(orderArray,0,this.currentIndex-1);
           }

           private void GuiBinOrder(int[] orderArray,int begin,int end) {
                 if(end==begin) { //当数组不可拆分时,即只有一个元素时
                      return;
                 }
                 int middle = (begin+end)/2;
                 this.GuiBinOrder(orderArray,begin, middle); //递归的思想:对左半边数组进行拆分
                 this.GuiBinOrder(orderArray,middle+1, end); //递归的思想:对右半边数组进行拆分
                 this.order(orderArray,begin,middle+1,end);//归并的思想:对子数组进行排序合并
            }

          private void order(int[] orderArray,int begin,int middle,int end) {
                   int i = begin;
                   int j = middle;//右边子数组起始
                   int mid = middle-1;//左边子数组尾
                   int size = end-begin+1;
                   int index = 0;

                   while(i<=mid&&j<=end) {     //A[0]>B[0] ? C[0]=B[0] : C[0]=A[0];  比较并插入数组C   A数组至关于左边子数组,B数组至关于右边子数组。
                            if(this.Array[i]>this.Array[j]) {
                                  orderArray[index++]=this.Array[j++];
                            }else {
                                  orderArray[index++]=this.Array[i++];
                            }
                  };

                  while(i<=mid) {//当右边子数组B为空时,左边子数组A依然有元素,将剩余元素依次插入数组C
                            orderArray[index++] = this.Array[i++];
                  };

                  while(j<=end) {//当左边子数组A为空时,右边子数组B依然有元素,将剩余元素依次插入数组C
                           orderArray[index++] = this.Array[j++];
                  };

                  for(index=0;index<size;index++) { //将额外开销数组中已排序好的元素依次从 本次递归起始点复制回原数组
                           this.Array[begin+index] = orderArray[index];
                  }
          }

           public void show() {
                   for (int i : Array) {
                       System.out.println(i);
                   }
           }

}

排序结果为:4、15、21、32、58、61、75、78、83、89

相关文章
相关标签/搜索