为什么这些额外的代码行会导致河内的"塔楼#34;举措数量增加?

时间:2016-01-09 00:47:40

标签: java towers-of-hanoi

我的讲师在测试中告诉我们以下内容:

" 给出以下代码:

int count=0;
static void towersOfhanoi(int n, char source, char target, char spare)
    {    
        count++;
        if (n==1)
            System.out.println("move a disk from "+source+" to "+target);
         else
         {  
            towersOfhanoi(n-1, source, spare, target); 

            System.out.println("move a disk from "+source+" to "+target);

            towersOfhanoi(n-1, spare, target, source); 
            towersOfhanoi(1, spare, source, target); 
            towersOfhanoi(n-1, source, spare, target); 

在执行了towerofhanoi(11,A,B,C)之后移动的价值是什么?"

我回家编程了这个并且移动次数增加了,在我插入这些代码行之前,我将其称为 A (使用11个磁盘,产生了118097次移动!) :

            towersOfhanoi(n-1, spare, target, source); 
            towersOfhanoi(1, spare, source, target); 
            towersOfhanoi(n-1, source, spare, target); 

在插入这些代码之前,我已将这些代码放在其位置。我将其称为 B (使用11个磁盘,生成2047次移动):

            towersOfhanoi(n-1, spare, target, source); 

我的问题是, A 中的3行代码做了什么?为什么移动的数量会发生变化,是否有计算移动次数的公式?我知道可以使用"(2 ^ 11)-1"来计算移动量。对于 B 。任何反馈都会有所帮助。

1 个答案:

答案 0 :(得分:2)

嗯, B 线是河内塔问题的正确解决方案。 A 而不是 B 的三行正是他们所说的:他们用这些参数递归地调用函数。第一行与 B 相同,所以这是正确的。其他两行在问题方面没有意义。你把它们放在那里,所以问题更多:为什么你这样做?

我猜你想要做以下事情:

   if (n==1) {
        System.out.println("move a disk from "+source+" to "+target);
   } else {
        towersOfhanoi(n-1, source, spare, target); 
        towersOfhanoi(1, source, target, spare); 
        towersOfhanoi(n-1, spare, target, source); 
   }

这将是河内塔的另一个正确表达问题,其移动次数与原来的 B 相同。

至于公式:如果我们将n个磁盘的移动次数定义为N(n),则原始解决方案解决方案为移动次数(遵循源代码):

N(n) = N(n-1) + 1 + N(n-1) 
     = 2 * N(n-1) + 1
     = 2 * (2 * (2 * ... (2 * 1 + 1) ... + 1) + 1) + 1)
     = 2^(n-1) + 2^(n-2) + 2^(n-3) + ... + 1
     = (1 - 2^n) / (1 - 2)
     = 2^n - 1

对A代码的类似推理:

N(n) = N(n-1) + 1 + N(n-1) + 1 + N(n-1)
     = 3 * N(n-1) + 2
     = 3^(n-1) + 2 * (3^(n-2) + ... + 1)
     = 3^(n-1) + 2 * (1-3^(n-1)) / (1-3)
     = 2 * 3^(n-1) - 1