【问题标题】:Preorder traversal visualization of binary tree二叉树的前序遍历可视化
【发布时间】:2013-05-16 00:15:59
【问题描述】:

我决定从http://rosettacode.org/wiki/Tree_traversal#C.2B.2B 获取代码并使用 SDL 将其可视化。页面上的 ASCII 图形如下所示:

         1
        / \
       /   \
      /     \
     2       3
    / \     /
   4   5   6
  /       / \
 7       8   9

但到目前为止我设法得到的结果看起来像:

ASCII:

        1
      2 
    4   3
  7   6
    8
      9

注意缺少的 5。6 绘制在它上面(通过位置的调试输出验证。)

还有我的问题代码:

作为对指出错字的回应,我将从我的源文件中复制/粘贴原样:

  void preorderTraverse(int x = osd.position.x, int y = osd.position.y) const {
    osd.position.x = x;
    osd.position.y = y;
    std::cout << "Debug: " << x << " " << y << " " << getValue() << std::endl;
    osd.put(getValue());
    if(mLeft)  {  x -= 50; y += 30; mLeft->preorderTraverse(x, y);}
    if(mRight) {  x += 50; y += 30; mRight->preorderTraverse(x, y);}
  }

想法是它遵循遍历的递归性质,但是当它遍历右侧时似乎有问题。

请注意,我将默认参数设置为 osd.position,因为它们是这样定义的:

position.x = SCREEN_WIDTH / 2 - 50/2;
position.y = 0;

而 osd.put 是:

SDL_Rect offset = get_offset(num);

SDL_BlitSurface( number_chart_, &offset, screen, &position );

offset 是源矩形(即,blitting 图像)。get_offset 只是对数字的 sprite 表进行切片。

所以我的问题是如何修复 preorderTraverse 看起来像 ascii 图形?不用做复杂的事情,比如检查整棵树的宽度等,只要正确嵌套即可。

【问题讨论】:

  • 那是你的真实代码吗? x -= graphicWidth 两个 mLeft mRight?
  • 我不知道那个错字是怎么出现的,但它不在我的源文件中。我得到的图像是从源文件构建的,没有错字。

标签: c++ sdl binary-tree tree-traversal


【解决方案1】:

您的代码中有一个简单的错误。对于正确的孩子,您应该添加x,而不是从中减去。也就是说,你应该这样做:

if(mRight) 
{
    x += graphicWidth; // <-- Note the "+" here.
    y += graphicHeight; 
    mRight->preorderTraverse(x, y);
}

但这不会解决你所有的问题。我认为你在每次递归中添加或减去 x 的数量应该取决于你在树中的深度。

作为您可以执行的操作的示例,请尝试以下操作。向preorderTraverse 添加另一个名为xstride 的参数,如下所示:

void preorderTraverse(int xstride, int x, int y) const

并在第一次调用时像这样初始化它:

preorderTraverse (SCREEN_WIDTH / 4, /*some value for X*/, /*some value for Y*/)

然后,在函数体中,将xstridex 相加/减去:

x += xstride; // or x -= xstride. Also see the end note.

在每次递归调用 preorderTraverse 时,您将 xstride 除以 2:

mLeft->preorderTraverse (xstride / 2, x, y); // or mRight->...

注意:您可能需要将graphicWidth 添加到xstride 或从x 中添加/减去它。

【讨论】:

  • 当我将代码转移到问题中时出现了错字。我用graphicWidth替换了50并且不小心添加了错字。我还是有这个问题。
  • 好的。试试我的其余答案,看看是否有帮助。我将删除答案中现在多余的部分。
  • 你能发布一个更完整的代码示例吗?我无法让它工作。
【解决方案2】:

你的逻辑在这里完全是错误的。

if(mLeft)  {  x -= 50; y += 30; mLeft->preorderTraverse(x, y);}
if(mRight) {  x += 50; y += 30; mRight->preorderTraverse(x, y);}

看看它,想想如果 both mLeft mRight 都存在,x 会发生什么。你减去 50 然后再加回来mRight 以与父级相同的 x 坐标结束。

y 一样,您将添加 30 两次

你想要这样的东西。

if(mLeft)  {  mLeft->preorderTraverse(x - 50, y + 30);}
if(mRight) {  mRight->preorderTraverse(x + 50, y + 30);}

【讨论】:

    猜你喜欢
    • 2021-03-08
    • 2023-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-13
    • 1970-01-01
    相关资源
    最近更新 更多