1

http://rosettacode.org/wiki/Tree_traversal#C.2B.2Bからコードを取得し、SDL を使用して視覚化することにしました。ページ上の ASCII グラフィックは次のようになります。

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

しかし、これまでに得た結果は次のようになります。

http://i41.tinypic.com/x0ts7m.png

アスキー:

        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 は、ソースの四角形です (つまり、イメージをブリッティングします)。 get_offset は、単純に数値のスプライト シートをスライスします。

私の質問は、preorderTraverse を ASCII グラフィックのように修正するにはどうすればよいですか? ツリー全体の幅をチェックするなどの複雑なことをする必要はなく、適切にネストするだけです。

4

2 に答える 2

0

コードに単純なバグがあります。適切な子の場合は、足す必要がxあり、引き算しないでください。つまり、次のようにする必要があります。

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

しかし、これですべての問題が解決するわけではありません。各再帰で加算または減算する量xは、ツリー内の深さに依存する必要があると思います。

できることの例として、次のことを試してください。次のように、別のパラメーターをpreorderTraversecalledに追加します。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.

を再帰的に呼び出すたびに、次のように 2preorderTraverseで除算します。xstride

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

注:に/から追加/減算graphicWidthするときに、おそらく追加する必要があります。xstridex

于 2013-05-15T09:23:46.330 に答える
0

ここでは、あなたの論理は単に間違っています。

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

それを見て、との両方が存在するとどうなるか考えてみてxください。50を引いてから足し戻します。 親と同じ x 座標になります。 mLeft mRightmRight

同様に、 30を 2 回y追加しています。

あなたはこのようなものが欲しかった。

if(mLeft)  {  mLeft->preorderTraverse(x - 50, y + 30);}
if(mRight) {  mRight->preorderTraverse(x + 50, y + 30);}
于 2013-05-15T16:15:59.353 に答える