首页 > 代码库 > 浅谈递归和分治
浅谈递归和分治
今天要谈论的话题主要是递归和分治。为什么要将分治和递归放在一起说?很简单,因为这两兄弟几乎不分家。就我所见过的,任何用到分治思想的算法就没有不用递归的。(如果某位朋友知道例外的,请不吝赐教。)
所谓递归,就是自己调用自己。第一步是设置基值条件用于方法的返回,否则方法将不停的自调用,直到程序崩溃。第二部是缩小问题域的范围并调用自己来求解,直到范围缩小到触发基值条件为止。
所谓分治,即分而治之。它也分两步:一,把一个大的问题域分解为小的问题域。二,对每个小的问题域按步骤一办理。(单从这句话来说,我们就明显看到递归的影子了。)
概念说清楚了,接下来还是拿递归分治最经典的一个算法——递归二叉查找——来举例。
先贴代码
1 public class BinarySearchApp { 2 public static final int SIZE = 10; 3 public static int[] arrays = new int[SIZE]; 4 5 public static int binarySearch(int lower,int upper,int key) { 6 7 if(lower > upper) 8 return -1;//-1表示找不到 9 else {10 int current = (lower+upper)/2;11 if(arrays[current] == key)12 return current;13 else if(arrays[current] > key)14 return binarySearch(lower, current-1, key);//从下半截查找15 else16 return binarySearch(current+1, upper, key);//从上半截查找17 }18 }19 20 public static void main(String[] args) {21 for(int i=0;i<10;i++)22 arrays[i]=i;23 System.out.println(binarySearch(0,SIZE-1,3));//查找3是第几个24 System.out.println(binarySearch(0,SIZE-1,9));//查找3是第几个25 System.out.println(binarySearch(0,SIZE-1,15));//查找3是第几个26 }27 }
下面是运行结果
这个算法是从一个有序数组中查找一个特定的值并返回它的索引,它很好的体现了递归和分治的思想。首先,找出数组中间位置的值,将这个值与要查找的Key比较,如果相同,返回该位置。如果小于Key,就在数组的上半截查找,如果大于Key,就在数组的下半截查找。重复上面的流程直到找到结果或返回-1。该算法的时间复杂度仅为O(LogN)。当然,在调用该方法前,最好先判断一下Key是否位于数组最小值与最大值之间,在某些情况下可以有效提高效率。
好了,今天的随笔差不多就要就结束了。最后给大家分享一个有意思的小算法——汉诺塔问题,为什么说它有意思呢?一般解汉诺塔问题的算法都是求出一共花多少次可以移完圆盘。老实说这个真心无聊,只要高中学过数学归纳法就能很容易算出来,一点体现不出计算机的优势。我这里给出的程序可以打印出整个移动过程的步骤。
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStreamReader; 4 public class Hanoi { 5 public static void main(String[] args) throws IOException { 6 System.out.println("Please input the number of disk:"); 7 int nDisks = getInt(); 8 doTower(nDisks,‘A‘,‘B‘,‘C‘); 9 }10 11 public static String getString() throws IOException {12 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));13 return reader.readLine();14 }15 public static int getInt() throws IOException {16 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));17 String string = reader.readLine();18 return Integer.parseInt(string);19 }20 public static void doTower(int topN,char from,char inter,char to) {21 if(topN == 1)22 System.out.println("Disk "+topN+" from "+from+" to "+to);23 else {24 doTower(topN-1, from, to, inter);//from --> inter25 System.out.println("Disk "+topN+" from "+from+" to "+to);26 doTower(topN-1, inter, from, to);//inter --> to27 }28 }29 }
运行结果贴在下面
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。