(9)遞歸 《java數據結構與算法》一書第六章讀書筆記


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
遞歸 是一種方法(函數)調用自己的編程技術
++++++++++++++++++++++++++++++++++++++++++++++++
三角數字 1,3,6,10,15.....數列中第n項是由 第n-1項的值加上n得到的。

遞歸:
int triangle(int n){
   if(n==1)
      return 1;     //遞歸的出口
   else
      return ( n+triangle(n-1) )
}

++++++++++++++++++++++++++++++++++++++++++++++++++
階乘 
1 1*1     1
2 2*1     2
3 3*2*1   6
4 4*3*2*1 24
遞歸
int factorial(int n){
   if(n ==1){
       return 1;
   }else{
       return ( n*factorial(n-1) )
   }
}
++++++++++++++++++++++++++++++++++++++++++++++++++
變位字 !!!!《*****》

++++++++++++++++++++++++++++++++++++++++++++++++++
遞歸的二分查找
遞歸的二分查找《while循環 變成了 遞歸調用》
++++++++++++++++++++++++++++++++++++++++++++++++++

漢諾塔問題

++++++++++++++++++++++++++++++++++++++++++++++++++
歸併排序:
歸併排序比簡單排序《冒泡、選擇、插入》高效,冒泡、選擇、插入都要用O(N^2)時間。而歸併排序只要O(N*logN)
若N爲10000的話, N^2爲100000000(億)  N*logN爲40000。換成時間的比例,歸併耗時40秒。則插入耗時28個小時。
缺點:需要在存儲器中 有另一個 大小等於被排序數據項數據的數組。如果有足夠的存儲空間,歸併是個不錯選擇。

歸併兩個有序數組
歸併算法的中心是歸併兩個已經有序的數組。歸併兩個有序數組AB,就生成第三個數組C。數組C包含AB的所有項。
核心代碼: 注意三個while循環的寫法!!!
  public static void merge( int[] arrayA, int sizeA,
                               int[] arrayB, int sizeB,
                               int[] arrayC )
      {
      int aDex=0, bDex=0, cDex=0;


      while(aDex < sizeA && bDex < sizeB)  // neither array empty
         if( arrayA[aDex] < arrayB[bDex] )
            arrayC[cDex++] = arrayA[aDex++];
         else
            arrayC[cDex++] = arrayB[bDex++];


      while(aDex < sizeA)                  // arrayB is empty,
         arrayC[cDex++] = arrayA[aDex++];  // but arrayA isn't


      while(bDex < sizeB)                  // arrayA is empty,
         arrayC[cDex++] = arrayB[bDex++];  // but arrayB isn't
      }  // end merge()

真正的歸併排序:
核心思想:把一個數組分成兩半,排序每一半。然後用merge()方法把數組的兩半歸併成一個有序數組。
如何爲每一部分排序呢? 遞歸。
核心代碼:
 public void mergeSort()           // called by main()
      {                              // provides workspace
      long[] workSpace = new long[nElems];
      recMergeSort(workSpace, 0, nElems-1); //第一次調用 開始的腳標0  最大的 nElems-1
      }
   //-----------------------------------------------------------
   private void recMergeSort(long[] workSpace, int lowerBound,  int upperBound)
      {
      if(lowerBound == upperBound)            // if range is 1,
         return;                              // no use sorting
      else
         {                                    // find midpoint
         int mid = (lowerBound+upperBound)/2;
                                              
         recMergeSort(workSpace, lowerBound, mid);  // sort low half
         recMergeSort(workSpace, mid+1, upperBound);// sort high half
                                              
         merge(workSpace, lowerBound, mid+1, upperBound);// merge them  
         }  // end else
      }  // end recMergeSort()
   //-----------------------------------------------------------
   private void merge(long[] workSpace, int lowPtr,  int highPtr, int upperBound)
      {
      int j = 0;                             // workspace index
      int lowerBound = lowPtr;
      int mid = highPtr-1;
      int n = upperBound-lowerBound+1;       // # of items


      while(lowPtr <= mid && highPtr <= upperBound)
         if( theArray[lowPtr] < theArray[highPtr] )
            workSpace[j++] = theArray[lowPtr++];
         else
            workSpace[j++] = theArray[highPtr++];


      while(lowPtr <= mid)
         workSpace[j++] = theArray[lowPtr++];


      while(highPtr <= upperBound)
         workSpace[j++] = theArray[highPtr++];


      for(j=0; j<n; j++)
         theArray[lowerBound+j] = workSpace[j];
      }  // end merge()
++++++++++++++++++++++++++++++++++++++++++++++++++
消除遞歸:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

《1》三角數字 遞歸

// triangle.java
// evaluates triangular numbers
// to run this program: C>java TriangleApp
import java.io.*;
////////////////////////////////////////////////////////////////
class TriangleApp
   {
   static int theNumber;


   public static void main(String[] args) throws IOException
      {
      System.out.print("Enter a number: ");
      theNumber = getInt();
      int theAnswer = triangle(theNumber);
      System.out.println("Triangle="+theAnswer);
      }  // end main()
//-------------------------------------------------------------
   public static int triangle(int n)
      {
      if(n==1)
         return 1;
      else
         return  ( n + triangle(n-1) );
      }
//-------------------------------------------------------------
   public static String getString() throws IOException
      {
      InputStreamReader isr = new InputStreamReader(System.in);
      BufferedReader br = new BufferedReader(isr);
      String s = br.readLine();
      return s;
      }
//-------------------------------------------------------------
   public static int getInt() throws IOException
      {
      String s = getString();
      return Integer.parseInt(s);
      }
//--------------------------------------------------------------
   }  // end class TriangleApp
////////////////////////////////////////////////////////////////
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
《2》變位字 遞歸
// anagram.java
// creates anagrams
// to run this program: C>java AnagramApp
import java.io.*;
////////////////////////////////////////////////////////////////
class AnagramApp
   {
   static int size;
   static int count;
   static char[] arrChar = new char[100];
   //-----------------------------------------------------------
   public static void main(String[] args) throws IOException
      {
      System.out.print("Enter a word: ");    // get word
      String input = getString();
      size = input.length();                 // find its size
      count = 0;
      for(int j=0; j<size; j++)              // put it in array
         arrChar[j] = input.charAt(j);
      doAnagram(size);                       // anagram it
      }  // end main()
   //-----------------------------------------------------------
   public static void doAnagram(int newSize)
      {
      int limit;
      if(newSize == 1)                     // if too small,
         return;                           // go no further


      for(int j=0; j<newSize; j++)         // for each position,
         {
         doAnagram(newSize-1);             // anagram remaining
         if(newSize==2)                    // if innermost,
            displayWord();                 // display it
         rotate(newSize);                  // rotate word
         }
      }
   //-----------------------------------------------------------
   // rotate left all chars from position to end
   public static void rotate(int newSize)
      {
      int j;
      int position = size - newSize;
      char temp = arrChar[position];       // save first letter
      for(j=position+1; j<size; j++)       // shift others left
         arrChar[j-1] = arrChar[j];
      arrChar[j-1] = temp;                 // put first on right
      }
   //-----------------------------------------------------------
   public static void displayWord()
      {
      if(count < 99)
         System.out.print(" ");
      if(count < 9)
         System.out.print(" ");
      System.out.print(++count + " ");
      for(int j=0; j<size; j++)
         System.out.print( arrChar[j] );
      System.out.print("   ");
      System.out.flush();
      if(count%6 == 0)
         System.out.println("");
      }
   //-----------------------------------------------------------
   public static String getString() throws IOException
      {
      InputStreamReader isr = new InputStreamReader(System.in);
      BufferedReader br = new BufferedReader(isr);
      String s = br.readLine();
      return s;
      }
   //-----------------------------------------------------------
   }  // end class AnagramApp
////////////////////////////////////////////////////////////////


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


《3》遞歸的二分查找《while循環 變成了 遞歸調用》
// binarySearch.java
// demonstrates recursive binary search
// to run this program: C>java BinarySearchApp
////////////////////////////////////////////////////////////////
class ordArray
   {
   private long[] a;                 // ref to array a
   private int nElems;               // number of data items
   //-----------------------------------------------------------
   public ordArray(int max)          // constructor
      {
      a = new long[max];             // create array
      nElems = 0;
      }
   //-----------------------------------------------------------
   public int size()
      { return nElems; }
   //-----------------------------------------------------------
   public int find(long searchKey)
      {
      return recFind(searchKey, 0, nElems-1);
      }
   //-----------------------------------------------------------
   private int recFind(long searchKey, int lowerBound,
                                         int upperBound)
      {
      int curIn;


      curIn = (lowerBound + upperBound ) / 2;
      if(a[curIn]==searchKey)
         return curIn;              // found it
      else if(lowerBound > upperBound)
         return nElems;             // can't find it
      else                          // divide range
         {
         if(a[curIn] < searchKey)   // it's in upper half
            return recFind(searchKey, curIn+1, upperBound);
         else                       // it's in lower half
            return recFind(searchKey, lowerBound, curIn-1);
         }  // end else divide range
      }  // end recFind()
   //-----------------------------------------------------------
   public void insert(long value)    // put element into array
      {
      int j;
      for(j=0; j<nElems; j++)        // find where it goes
         if(a[j] > value)            // (linear search)
            break;
      for(int k=nElems; k>j; k--)    // move bigger ones up
         a[k] = a[k-1];
      a[j] = value;                  // insert it
      nElems++;                      // increment size
      }  // end insert()
   //-----------------------------------------------------------
   public void display()             // displays array contents
      {
      for(int j=0; j<nElems; j++)       // for each element,
         System.out.print(a[j] + " ");  // display it
      System.out.println("");
      }
   //-----------------------------------------------------------
   }  // end class ordArray
////////////////////////////////////////////////////////////////
class BinarySearchApp
   {
   public static void main(String[] args)
      {
      int maxSize = 100;             // array size
      ordArray arr;                  // reference to array
      arr = new ordArray(maxSize);   // create the array


      arr.insert(72);                // insert items
      arr.insert(90);
      arr.insert(45);
      arr.insert(126);
      arr.insert(54);
      arr.insert(99);
      arr.insert(144);
      arr.insert(27);
      arr.insert(135);
      arr.insert(81);
      arr.insert(18);
      arr.insert(108);
      arr.insert(9);
      arr.insert(117);
      arr.insert(63);
      arr.insert(36);


      arr.display();                 // display array


      int searchKey = 27;            // search for item
      if( arr.find(searchKey) != arr.size() )
         System.out.println("Found " + searchKey);
      else
         System.out.println("Can't find " + searchKey);
      }  // end main()
   }  // end class BinarySearchApp
////////////////////////////////////////////////////////////////


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
《4》 漢諾塔問題
// towers.java
// solves Towers of Hanoi puzzle
// to run this program: C>java TowersApp
////////////////////////////////////////////////////////////////
class TowersApp
   {
   static int nDisks = 3;


   public static void main(String[] args)
      {
      doTowers(nDisks, 'A', 'B', 'C');
      }
   //-----------------------------------------------------------
   public static void doTowers(int topN,
                               char src, char inter, char dest)
      {
      if(topN==1)
         System.out.println("Disk 1 from " + src + " to "+ dest);
      else
         {
         doTowers(topN-1, src, dest, inter);   // src to inter


         System.out.println("Disk " + topN +   // move bottom
                            " from " + src + " to "+ dest);
         doTowers(topN-1, inter, src, dest);   // inter to dest
         }
      }
//-------------------------------------------------------------
   }  // end class TowersApp
////////////////////////////////////////////////////////////////
《5》歸併排序  歸併兩個有序數組
// merge.java
// demonstrates merging two arrays into a third
// to run this program: C>java MergeApp
////////////////////////////////////////////////////////////////
class MergeApp
   {
   public static void main(String[] args)
      {
      int[] arrayA = {23, 47, 81, 95};
      int[] arrayB = {7, 14, 39, 55, 62, 74};
      int[] arrayC = new int[10];


      merge(arrayA, 4, arrayB, 6, arrayC);
      display(arrayC, 10);
      }  // end main()
   //-----------------------------------------------------------
                                       // merge A and B into C
     public static void merge( int[] arrayA, int sizeA,
                               int[] arrayB, int sizeB,
                               int[] arrayC )
      {
      int aDex=0, bDex=0, cDex=0;


      while(aDex < sizeA && bDex < sizeB)  // neither array empty
         if( arrayA[aDex] < arrayB[bDex] )
            arrayC[cDex++] = arrayA[aDex++];
         else
            arrayC[cDex++] = arrayB[bDex++];


      while(aDex < sizeA)                  // arrayB is empty,
         arrayC[cDex++] = arrayA[aDex++];  // but arrayA isn't


      while(bDex < sizeB)                  // arrayA is empty,
         arrayC[cDex++] = arrayB[bDex++];  // but arrayB isn't
      }  // end merge()
   //-----------------------------------------------------------
                                       // display array
   public static void display(int[] theArray, int size)
      {
      for(int j=0; j<size; j++)
         System.out.print(theArray[j] + " ");
      System.out.println("");
      }
   //-----------------------------------------------------------
   }  // end class MergeApp
////////////////////////////////////////////////////////////////


(6)歸併排序  ---- 利用遞歸的思想
// mergeSort.java
// demonstrates recursive merge sort
// to run this program: C>java MergeSortApp
////////////////////////////////////////////////////////////////
class DArray
   {
   private long[] theArray;          // ref to array theArray
   private int nElems;               // number of data items
   //-----------------------------------------------------------
   public DArray(int max)            // constructor
      {
      theArray = new long[max];      // create array
      nElems = 0;
      }
   //-----------------------------------------------------------
   public void insert(long value)    // put element into array
      {
      theArray[nElems] = value;      // insert it
      nElems++;                      // increment size
      }
   //-----------------------------------------------------------
   public void display()             // displays array contents
      {
      for(int j=0; j<nElems; j++)    // for each element,
         System.out.print(theArray[j] + " ");  // display it
      System.out.println("");
      }
   //-----------------------------------------------------------
   public void mergeSort()           // called by main()
      {                              // provides workspace
      long[] workSpace = new long[nElems];
      recMergeSort(workSpace, 0, nElems-1); //第一次調用 開始的腳標0  最大的 nElems-1
      }
   //-----------------------------------------------------------
   private void recMergeSort(long[] workSpace, int lowerBound,  int upperBound)
      {
      if(lowerBound == upperBound)            // if range is 1,
         return;                              // no use sorting
      else
         {                                    // find midpoint
         int mid = (lowerBound+upperBound)/2;
                                              
         recMergeSort(workSpace, lowerBound, mid);  // sort low half
         recMergeSort(workSpace, mid+1, upperBound);// sort high half
                                              
         merge(workSpace, lowerBound, mid+1, upperBound);// merge them  
         }  // end else
      }  // end recMergeSort()
   //-----------------------------------------------------------
   private void merge(long[] workSpace, int lowPtr,  int highPtr, int upperBound)
      {
      int j = 0;                             // workspace index
      int lowerBound = lowPtr;
      int mid = highPtr-1;
      int n = upperBound-lowerBound+1;       // # of items


      while(lowPtr <= mid && highPtr <= upperBound)
         if( theArray[lowPtr] < theArray[highPtr] )
            workSpace[j++] = theArray[lowPtr++];
         else
            workSpace[j++] = theArray[highPtr++];


      while(lowPtr <= mid)
         workSpace[j++] = theArray[lowPtr++];


      while(highPtr <= upperBound)
         workSpace[j++] = theArray[highPtr++];


      for(j=0; j<n; j++)
         theArray[lowerBound+j] = workSpace[j];
      }  // end merge()
   //-----------------------------------------------------------
   }  // end class DArray
////////////////////////////////////////////////////////////////
class MergeSortApp
   {
   public static void main(String[] args)
      {
      int maxSize = 100;             // array size
      DArray arr;                    // reference to array
      arr = new DArray(maxSize);     // create the array


      arr.insert(64);                // insert items
      arr.insert(21);
      arr.insert(33);
      arr.insert(70);
      arr.insert(12);
      arr.insert(85);
      arr.insert(44);
      arr.insert(3);
      arr.insert(99);
      arr.insert(0);
      arr.insert(108);
      arr.insert(36);


      arr.display();                 // display items


      arr.mergeSort();               // merge sort the array


      arr.display();                 // display items again
      }  // end main()
   }  // end class MergeSortApp
////////////////////////////////////////////////////////////////












發佈了55 篇原創文章 · 獲贊 4 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章