Java将递归改成循环的通用方法

来源:互联网 发布:mac作图软件 编辑:程序博客网 时间:2024/06/05 05:00
用Stack或LinkedList来实现内存中的出栈入栈过程,即可将递归改成循环。正式开始前先厘清几个概念:循环(loop) - 最基础的概念, 所有重复的行为递归(recursion) - 在函数内调用自身, 将复杂情况逐步转化成基本情况(数学)迭代(iterate) - 在多次循环中逐步接近结果(编程)迭代(iterate) - 按顺序访问线性结构中的每一项遍历(traversal) - 按规则访问非线性结构中的每一项确切地说,递归也属于循环。下文中的「循环」特指非递归的循环。第一个例子用求阶乘,顺便加了迭代方法。[java] view plain copyimport java.util.Stack;    public class Factorial{      public static void main(String[] args){          Factorial f = new Factorial();          System.out.println(f.recursion(5));          System.out.println(f.loop(5));          System.out.println(f.iteration(5));      }        /**      * 递归求阶乘      */      public int recursion(int n){          if (n == 1) return 1;          return recursion(n-1) * n;      }        /**      * 循环求阶乘      */      public int loop(int n){          Stack<Integer> stack = new Stack<Integer>();          int result = 1;          stack.push(n);          while(!stack.isEmpty()){              n = stack.pop();              result *= n;              if (n > 1) stack.push(n-1);          }          return result;      }        /**      * 迭代求阶乘      */      public int iteration(int n){          int result = 1;          for(int i = 1; i <= n; i++){              result *= i;          }          return result;      }  }  第二个例子是快速排序。递归快排大量数量时,容易爆栈。这时可以改成循环。[java] view plain copyimport java.util.Random;    public class Sorts{      private static Random rand = new Random();        public static void main(String[] args){          int[] a = {49,38,65,97,76,13,27,49,78,34,12,64,5,4,62              ,99,98,54,56,17,18,23,34,15,35,25,53,51};           quickSort(a);          System.out.println(Arrays.toString(a));          int[] a = {49,38,65,97,76,13,27,49,78,34,12,64,5,4,62              ,99,98,54,56,17,18,23,34,15,35,25,53,51};           quickSortByLoop(a);          System.out.println(Arrays.toString(a));      }        /**      * 快速排序      * 递归实现      */      private static void quickSort(int[] arr, int start, int end){          if (start >= end) return;          int base = arr[start + rand.nextInt(end-start+1)]; //中轴值          int left = start, right = end; //指示左右两端未排序的边界索引          int i = start; // 用于排序          while(i <= right){              if (arr[i] < base){ //小于中轴值则移到左侧                  swap(arr, left++, i++);              }else if (arr[i] > base){ //大于中轴值则移到右侧                  swap(arr, right--, i); //当前i位置的值未排序,故i不自增              }else{                  i++;              }          }          //排完后left左侧均为小于base的数,right右侧均为大于base的数          quickSort(arr, start, left-1);          quickSort(arr, right+1, end);      }          /**      * 快速排序      * 循环实现      */      private static quickSortByLoop(int[] arr){          Stack<Integer> stack = new Stack<Integer>();          int start = 0;          int end = arr.length - 1;          stack.push(start);          stack.push(end);          while(!stack.isEmpty()){              end = stack.pop(); // 顺序很重要              start = stack.pop();              if (start < end){ // 开始排序                  int i = start;                  int base = arr[start + rand.nextInt(end-start+1)]                  int left = start;                  int right = end;                  while(i <= right){                      if (arr[i] < base){                          swap(arr, left++, i++);                      }else if (arr[i] > base){                          swap(arr, right--, i);                      }else {                          i++;                      }                  }                  // ----右半边----                  stack.push(right + 1);                  stack.push(end);                  // ----左半边----                  stack.push(start);                  stack.push(left - 1);              }          }      }  }  

 

0 0
原创粉丝点击