遞歸-歸併排序 思想 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

相關文章
相關標籤/搜索