我决定从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只是切片一个精灵数字。
所以我的问题是如何修复preorderTraverse看起来像ascii图形?它不需要做复杂的事情,比如检查整棵树的宽度等,只需要正确嵌套。
答案 0 :(得分:0)
您的代码中存在一个简单的错误。对于正确的孩子,您应该添加到x
而不是从中减去。也就是说,你应该这样做:
if(mRight)
{
x += graphicWidth; // <-- Note the "+" here.
y += graphicHeight;
mRight->preorderTraverse(x, y);
}
但这将不解决所有问题。我认为您在每次递归时向x
添加或减去的数量应该取决于您在树中的深度。
作为您可以执行的操作的示例,请尝试以下操作。将另一个参数添加到名为preorderTraverse
的{{1}},如下所示:
xstride
并在第一次调用时将其初始化为:
void preorderTraverse(int xstride, int x, int y) const
然后,在函数体中,您将preorderTraverse (SCREEN_WIDTH / 4, /*some value for X*/, /*some value for Y*/)
添加到xstride
/从x
加减:
x += xstride; // or x -= xstride. Also see the end note.
并且在每次递归调用preorderTraverse
时,您将xstride
除以2:
mLeft->preorderTraverse (xstride / 2, x, y); // or mRight->...
注意:在graphicWidth
添加/减去xstride
时,您可能需要将x
添加到{{1}}。
答案 1 :(得分:0)
你的逻辑在这里完全错了。
if(mLeft) { x -= 50; y += 30; mLeft->preorderTraverse(x, y);}
if(mRight) { x += 50; y += 30; mRight->preorderTraverse(x, y);}
如果 x
和 mLeft
存在,请查看并考虑mRight
会发生什么。您减去50 ,然后将其添加回。 mRight
最终使用与父级相同的x坐标。
与y
同样,您添加30 两次。
你想要这样的东西。
if(mLeft) { mLeft->preorderTraverse(x - 50, y + 30);}
if(mRight) { mRight->preorderTraverse(x + 50, y + 30);}