zoukankan      html  css  js  c++  java
  • 七、递归

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

    总结:

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

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

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

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

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

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

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

  • 相关阅读:
    Docker学习(二): 镜像的使用与构建
    Docker学习(一): 基本概念
    SVN笔记
    标准Trie字典树学习二:Java实现方式之一
    标准Trie字典树学习一:原理解析
    SQL优化
    企业信息管理系统需求分析及要设计——程序的设计与实现①
    企业信息管理系统需求分析及要设计
    网络版ATM项目的实现——服务端
    网络版ATM项目的实现——客户端
  • 原文地址:https://www.cnblogs.com/xxlong/p/4990750.html
Copyright © 2011-2022 走看看