• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

dream311

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

七、递归

1、三角数字

// 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);
   }  
   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);
   }
} 

 

2、全排列

doAnagram(10):对于10个字符串的数组,选择第一个字符后,对后面的9个字符doAnagram(9),数组中字符再左移一个单位,再对后面的9个字符doAnagram(9)。也就是doAnagram(10)分为10个doAnagram(9),1个doAnagram(9)分为9个doAnagram(8),...,1个doAnagram(2)分为2个doAangram(1),doAnagram(1)则返回空,返回空后再打印。

// 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: ");   
      String input = getString();
      size = input.length();               
      count = 0;
      for(int j=0; j<size; j++)            
         arrChar[j] = input.charAt(j);
      doAnagram(size);                      
   }  

   public static void doAnagram(int newSize)
   {if(newSize == 1)                    
         return;                        
      for(int j=0; j<newSize; j++)         
      {
         doAnagram(newSize-1);           
         if(newSize==2)                   
            displayWord();                
         rotate(newSize);              
      }
   }
public static void rotate(int newSize) { int j; int position = size - newSize; char temp = arrChar[position]; for(j=position+1; j<size; j++) arrChar[j-1] = arrChar[j]; arrChar[j-1] = temp; } public static void displayWord() { System.out.print(++count + "、"); for(int j=0; j<size; j++) System.out.print( arrChar[j] ); 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; } }

 

3、二分查找

// to run this program: C>java BinarySearchAppclass ordArray
{
   private long[] a;                
   private int nElems;               
   public ordArray(int max)         
   {
      a = new long[max];             
      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; else if(lowerBound > upperBound) return nElems; else { if(a[curIn] < searchKey) return recFind(searchKey, curIn+1, upperBound); else return recFind(searchKey, lowerBound, curIn-1); } } public void insert(long value) { int j; for(j=0; j<nElems; j++) if(a[j] > value) break; for(int k=nElems; k>j; k--) a[k] = a[k-1]; a[j] = value; nElems++; } public void display() { for(int j=0; j<nElems; j++) System.out.print(a[j] + " "); System.out.println(""); }
} class BinarySearchApp { public static void main(String[] args) { int maxSize = 100; ordArray arr; arr = new ordArray(maxSize); arr.insert(72); 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(); int searchKey = 27; if( arr.find(searchKey) != arr.size() ) System.out.println("Found " + searchKey); else System.out.println("Can't find " + searchKey); } }

 

4、分治算法

递归的二分查找是分治算法的一个例子。把一个大问题分成两个相对来说更小的问题,并且解决每一个子问题。对每一个小问题的解决方法是一样的:把每个小问题分成两个更小的问题,并且解决它们。这个过程一直持续下去直到达到易于求解的基值情况,就不用再继续分了。

分治算法常常是一个方法,在这个方法中含有两个对自身的递归调用,分别对应于问题的两个部分。在二分查找中,就有两个这样的调用,但是只有一个真的执行了。后面的归并排序是真正执行了两个递归调用。

 

5、汉诺塔

三个塔A,B,C。盘子最开始在A,从上到下,一次编号1,2,3,4..,编号越大,盘子越大,最有要搬到C盘子上,从上到下,盘子依次变大

// to run this program: C>java TowersAppclass TowersApp
{
   static int nDisks = 5;

   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);   
         System.out.println("Disk " + topN +" from " + src + " to "+ dest);
         doTowers(topN-1, inter, src, dest);   
      }
   }
}

 

 

6、归并两个数组

// to run this program: C>java MergeAppclass 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);
   } 
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) if( arrayA[aDex] < arrayB[bDex] ) arrayC[cDex++] = arrayA[aDex++]; else arrayC[cDex++] = arrayB[bDex++]; while(aDex < sizeA) arrayC[cDex++] = arrayA[aDex++]; while(bDex < sizeB) arrayC[cDex++] = arrayB[bDex++]; } public static void display(int[] theArray, int size) { for(int j=0; j<size; j++) System.out.print(theArray[j] + " "); System.out.println(""); } }

 

 

7、归并排序

归并排序的思想是把一个数组分成两半,每一半再分成两半,一直到不能分为止,然后用merge()方法把的每两半归并成一个有序的数组。一直归并下去。

一个问题分成两个子问题,每个子问题又分成两个子问题,一直到易于求解的基值为止,再对每两个子问题归并排序,这是这两个子问题求解,再去求解子问题的父问题。

运行时间:O(N*logN)。需要一个大小与原来数组相等的工作空间

// to run this program: C>java MergeSortApp
class DArray
{
   private long[] theArray;         
   private int nElems;              

   public DArray(int max)          
   {
      theArray = new long[max];    
      nElems = 0;
   }

   public void insert(long value)    
   {
      theArray[nElems] = value;     
      nElems++;                      
   }
 
   public void display()          
   {
      for(int j=0; j<nElems; j++) 
         System.out.print(theArray[j] + " "); 
      System.out.println("");
   }

   public void mergeSort()           
   {                          
      long[] workSpace = new long[nElems];
      recMergeSort(workSpace, 0, nElems-1);
   }

   private void recMergeSort(long[] workSpace, int lowerBound,int upperBound)
   {
      if(lowerBound == upperBound)           
         return;                           
      else
      {                                  
         int mid = (lowerBound+upperBound) / 2;                                  
         recMergeSort(workSpace, lowerBound, mid);                                          
         recMergeSort(workSpace, mid+1, upperBound);                                             
         merge(workSpace, lowerBound, mid, upperBound);
      }  
   }  

   private void merge(long[] workSpace, int lowerBound,int mid, int upperBound)
   {
      int j = 0;  
      int n = upperBound-lowerBound+1;   
      int lowerPtr = lowerBound;    //lower那个数组的下标
      int upperPtr = mid+1;         //upper那个数组的下标                     

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

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

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

      for(j=0; j<n; j++)
         theArray[lowerBound+j] = workSpace[j];
   } 
}  

class MergeSortApp
{
   public static void main(String[] args)
   {
      int maxSize = 100;         
      DArray arr;                   
      arr = new DArray(maxSize);   

      arr.insert(64);          
      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();                 

      arr.mergeSort();           

      arr.display();               
   }  
}  

 

 

8、递归用栈来实现

int triangle(int n)
{
   if(n==1)
       return 1;
   else
       return(n+triangle(n-1));    
}

 

 

// to run this program: C>java StackTriangle2App
import java.io.*;              class StackX
{
   private int maxSize;     
   private int[] stackArray;
   private int top;          
   public StackX(int s)      
   {
      maxSize = s;
      stackArray = new int[maxSize];
      top = -1;
   }

   public void push(int p)   
   { stackArray[++top] = p; }

   public int pop()        
   { return stackArray[top--]; }

   public int peek()      
   { return stackArray[top]; }

   public boolean isEmpty()   
   { return (top == -1); }

}  class StackTriangle2App
   {
   static int theNumber;
   static int theAnswer;
   static StackX theStack;

   public static void main(String[] args) throws IOException
   {
      System.out.print("Enter a number: ");
      System.out.flush();
      theNumber = getInt();
      stackTriangle();
      System.out.println("Triangle="+theAnswer);
   } 
   public static void stackTriangle()
   {
      theStack = new StackX(10000);
      theAnswer = 0;                  

      while(theNumber > 0)        
      {
         theStack.push(theNumber);   
         --theNumber;               
      }
      while( !theStack.isEmpty() )
      {
         int newN = theStack.pop();   
         theAnswer += newN;         
      }
   }

   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);
      }

} 

 

 

总结:

一个递归的方法每次用不同的参数值反复调用自身。

某种参数值使递归的方法返回,而不再调用自身。这称为基值情况。

当递归方法返回时,递归过程通过逐渐完成各层方法实例的未执行部分,而从最内层返回到最外层的原始调用处。

对于三角数字,阶乘,单词字母全排列以及二分查找,它们的递归的方法只包含一次对自身的调用。

对于汉诺塔和归并排序,它们的递归的方法包括两次递归调用。

任何可以用递归完成的操作都可以用一个栈来实现。

递归的方法可能效能低,有时可以用一个简单循环或者是一个基于栈的方法来代替它。

 

posted on 2015-11-24 10:36  dream311  阅读(154)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3