了解c ++代码:使用递归的河内塔

时间:2019-02-09 18:02:23

标签: c++ recursion towers-of-hanoi

我正在学习c ++中的递归,但是被以下用于解决河内塔问题的c ++代码所困扰。

void Hanoi(int m, string start, string middle, string end){
    cout << "m is equal to: " << m << endl;
    if(m == 1){
        cout << "Move Disc " << " from " << start << "  to " << end << endl;
    }
    else{
        Hanoi(m-1,start,end,middle);
        cout << "Move disc " << m << " from " << start << " to " << end << endl;
        Hanoi(m-1,middle,start,end);
    }
}
int main(){
    int discs = 3;
    Hanoi(discs, "start","middle","end");

} 

代码输出如下:

m is equal to: 3
m is equal to: 2
m is equal to: 1
Move Disc  from start  to end
Move disc 2 from start to middle
m is equal to: 1
Move Disc  from end  to middle
Move disc 3 from start to end
m is equal to: 2
m is equal to: 1
Move Disc  from middle  to start
Move disc 2 from middle to end
m is equal to: 1
Move Disc  from start  to end

我的一般问题是我不了解递归的工作方式。为什么在执行“ if”语句之前将m设为1? m如何回到2?

4 个答案:

答案 0 :(得分:3)

如果将其打印为树状,则会得到以下内容:

main
  |--> hanoi(3, ...)
  |      |
  |      |--> hanoi(2, ...)
  |      |     |
  |      |     |--> hanoi(1, ...)
  |      |     |--> hanoi(1, ...)
  |      |<----|
  |      |--> hanoi(2, ...)
  |      |     |
  |      |     |--> hanoi(1, ...)
  |      |     |--> hanoi(1, ...)
  |      |<----|
  |<-----|
  |

对于每次对hanoi(m, ...)的调用,除非m == 1,它将两次继续调用hanoi(m-1,...)。在第一次调用中,它将再次调用hanoi(m-1,..)。 。)直到m为1。

因此,当m为2时向后走,它将连续两次调用hanoi(1,...):

   hanoi(2, ...)
      hanoi(1, ...)
      hanoi(1, ...)

当m为3时,它将连续两次调用hanoi(2,...),因此:

hanoi(3, ...)
   hanoi(2, ...)
      hanoi(1, ...)
      hanoi(1, ...)
   hanoi(2, ...)
      hanoi(1, ...)
      hanoi(1, ...)

答案 1 :(得分:0)

让我们从输出的第一部分开始: m is equal to: 3 m is equal to: 2 m is equal to: 1

首先像这样调用Hanoi函数:Hanoi(3)
由于在这种情况下是m != 1,因此我们将再次调用Hanoi(m-1)。这将产生上面的输出。现在,我们在此功能上深入了3个级别。

m == 1起,我们现在将看到以下输出: Move Disc from start to end

现在,我们退出最深的函数,并弹出回到函数调用堆栈的2级。现在我们输出: Move disc 2 from start to middle

答案 2 :(得分:-1)

此跟踪应该可以为您提供帮助,如果没有,那么您始终可以通过谷歌搜索“河内塔递归程序跟踪”来找到更多跟踪

Program trace

您还可以在https://javabypatel.blogspot.com/2015/12/tower-of-hanoi.html

找到该算法的工作原理

答案 3 :(得分:-1)

您的目标是将所有磁盘移动到另一个位置。

  • 要解决这个难题,您需要将塔从位置1移动到位置2。

  • 为此,您需要将最大的磁盘从位置1移动到位置2。

  • 为此,位置2必须为空,所有其他磁盘都必须位于位置3(大小为m-1的塔)。

  • 因此,您需要解决m-1大小的难题(将m-1大小的塔从位置1移到3)。这是第一个递归调用。

  • 现在,您可以将最大的磁盘从位置1移动到位置2。 这是递归函数调用之间的输出。

  • 现在您需要将大小为m-1的塔从位置3移动到位置2。

  • 因此,您需要再次解决m-1大小的难题(将m-1大小的塔从位置3移到2)。这是第二个递归函数调用。

如果没有这种递归,唯一可以解决的问题是将大小为1的塔移动到另一个地方,因为顶部没有任何磁盘,而您也可以移到其他任何磁盘的顶部。这就是在执行if语句之前m必须为1的原因。