hanoi问题求解

问题描述:Hanoi塔包括一对尺寸不等的圆盘和三个分别为A B C的针,初始状态为n个圆盘放在针A上。现在要讲圆盘从针A移动到针C上,一次只能用移动一个圆盘,并且一相同的顺序重新构建n个圆盘。在移动圆盘时,尺寸大的圆盘不允许放在尺寸小的圆盘上。

通常移动N个圆盘的算法需要移动2的n次方-1.


假以3个盘子的问题递归求解:

hanoi(int n,String initNeedle,String endNeedle,Strign tempNeedle);

分成三个阶段


1 使用三次移动将针A上面的两个圆盘移动到针B上

    hanoi(n-1,initNeedle,tempNeedle,endNeedle);

2 使用一次简单的移动将针A上面的最大圆盘移动到针C上(终止条件)

   

3 使用三次移动将针B上面的两个圆盘移动到针C上

   hanoi(n-1,tempNeedle,endNeedle,initNeedle);


package edu.cumt.jnotnull;

public class Hanoi {
	
	public static void hanoi(int n,String initNeedle,String endNeedle,String tempNeedle){
		if(n == 1){
			System.out.println("move "+initNeedle+" to " +endNeedle);
		}
		else{
			hanoi(n-1,initNeedle,tempNeedle,endNeedle);
			System.out.println("move "+initNeedle+" to "+endNeedle);
			hanoi(n-1,tempNeedle,endNeedle,initNeedle);
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		int n = 3;
		String beginNeedle = "A";
		middleNeedle = "B";
		endNeedle = "C";
		
		hanoi(n,beginNeedle,endNeedle,middleNeedle);
	}

}



复杂度分析
从n个盘子开始,将发生多少次移动?
令m(n)表示该算法解决n个盘子的问题所需的移动次数,很明显
m(1) = 1
对于n>1 算法使用了两个递归调用分别解决了两个n-1个盘子的问题,其中每个问题所需的移动次数都是m(n-1).因此从算法中可以看出
m(n)=m(n-1)+1+m(n-1) = 2m(n-1)+1
从这个等式中可见m(n) > 2m(n-1).也就是说 解决n个盘子的问题所需移动次数比解决n-1个盘子的问题多过两倍

按照m(n)=m(n-1)+1+m(n-1) = 2m(n-1)+1进行推算
m(1) =1;m(2)=3;m(3)=7;m(4)=15;m(5)=31;m(6)=63;
从而m(n) = 2^n -1

使用数学归纳法也能推出:
m(1) = 1;  2^1 - 1 = 1;所以该推测对于n=1成立
现在假使对于n=1,2,3...k,推测都是正确,现证明对m(k+1)也正确
m(k+1) = 2m(k)+1 = 2(2^k -1)+1 = 2^(k+1)-1
因为据推测对于n=k+1也是正确的,所以对于所有的n>=1都是正确的

你可能感兴趣的:(C++,c,算法,C#)