用10个板块递归c ++来解决河内的塔楼

时间:2014-10-16 17:07:53

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

试图解决河内的塔,我真的不明白为什么我的功能不起作用。我在这里检查了每个c ++解决方案。

bool CPlayer::MoveTop(int n, int from, int to)
{
    if (n == 0)
    {
        m_towers.MoveDisc(to, 1);
        return true;
    }

    MoveTop(n -1 , from , 1);

    m_towers.MoveDisc(1,from);

    MoveTop(n - 1, 1, to);

}// MoveTop

其中1是中间挂钩。并且m_tower.MoveDisc(to,from)将一个光盘从一个peg移动到另一个peg。

这是第一次调用函数MoveTop。

void CPlayer::OnRun()
{
    bool ok = MoveTop(10,0,2);

}// OnRun

我还有一个高度函数,可以返回被称为peg的板数,但我真的不认为我需要它。

添加了更多问题描述 所有的动作都显示在一个图形窗口中,在那里我可以看到板块从钉子移动到钉子的结果。现在,它不会简单地做它应该做的事情。当运行代码时,第一个平台移动到钉1(中间的钉)和“跳跃”上下。

这些是可用的功能:

高度功能:

int CTowers::Height(int tower)
{
    ASSERT( torn>=0 && torn<3 );

    return m_height[torn];
}

返回特定塔楼的高度。

int CTowers::TopSize(int tower)
{

        int h = Height(tower);
        if (h==0)
            return 1000;
        else return DiscSize(torn, h-1);
}

返回peg上的top的大小。

int CTowers::DiscSize(int tower, int place)
{
    ASSERT( place < Height(torn) );

    return m_pinne[tower][place];
}

返回指定的dicssize。

bool CTowers::MoveDisc(int to, int from)
{
  if (m_abort)
      return false;   //    

  m_pView->DrawAnimation( from, to );

  if (TopSize(from)>=TopSize(to))
        return false;
  m_numMoves++;
  int ds = Pop(from);
  Push(to, ds );
  m_pView->Invalidate();
  return true;
}

将光盘从一个挂钩移动到另一个挂钩。

1 个答案:

答案 0 :(得分:1)

这是一所古老的学校:)除以及征服问题。

尝试查看此代码:

void hanoi(int diskSize, int source, int dest, int spare)
{
  //This is our standard termination case. We get to here when we are operating on the 
  //smallest possible disk.
  if(diskSize == 0)
    {
        std::cout << "Move disk " << diskSize << " from peg " << source << " to peg " << dest << endl;
    }
    else
    {
        //Move all disks smaller than this one over to the spare.
        //So if diskSize is 5, we move 4 disks to the spare. This leaves us with 1 disk
        //on the source peg.
        //Note the placement of the params.
        //We are now using the dest peg as the spare peg. This causes each recursion to ping-pong
        //the spare and dest pegs.
        hanoi(diskSize - 1, source, spare, dest);

        //Move the remaining disk to the destination peg.
        std::cout << "Move disk "  << diskSize << " from peg " << source << " to peg " << dest << endl;

        //Move the disks we just moved to the spare back over to the dest peg.
        hanoi(diskSize - 1, spare, dest, source);
    }
}

有3个参数(source,dest,spare)的想法是每次能够知道哪个挂钩是备用挂钩,这样你就可以用它来放置磁盘。

如评论中所述,备用和目标之间的递归乒乓。

您的代码无法遵守您无法在较小的磁盘上放置较大磁盘的规则(请参阅 here )。所以你需要一个变量来保持目标钉,而不是像你的代码那样总是1

这就是你需要3个参数的原因。

干杯!