2016-05-19 4 views
1

バイナリ検索ツリー内のすべてのノードの内容を文字列と再帰を使って出力したいとします。問題は、このコードを使用すると、ルートの内容のみが表示されることです。その理由は、InOrder(BSTNode * bst_node)関数を再帰的に呼び出すたびに、私のstringstream変数が再度作成されるという理由がわかります。出力のためにストリングストリームを利用している間にこの問題を解決するために私のコードに行うことはできますか?stringstream C++を使用してバイナリ検索ツリー内のすべてのノードを再帰的に出力する方法

これは私のコードです:多分そのような

string BSTree::InOrder(BSTNode* bst_node) { 
    stringstream ss; 
    if (root_ == NULL) { 
    return ""; 
    } else { 
    if (bst_node->GetLeftChild() != NULL) { 
     InOrder(bst_node->GetLeftChild()); 
    } 
    ss << bst_node->GetContents() << " "; 
    if (bst_node->GetRightChild() != NULL) { 
     InOrder(bst_node->GetRightChild()); 
    } 
    } 
    return ss.str(); 
} 

答えて

3

何か?

string BSTree::InOrder(BSTNode* bst_node) 
{ 
    if (!bst_node) 
    return ""; 
    ostringstream ss; 
    ss << InOrder(bst_node->GetLeftChild()); 
    ss << bst_node->GetContents() << " "; 
    ss << InOrder(bst_node->GetRightChild()); 
    return ss.str(); 
} 

か、あなたはにstringstreamの同じインスタンスの周りに渡すことができます。

void BSTree::InOrderImpl(BSTNode* bst_node, ostringstream &ss) 
{ 
    if (bst_node) 
    { 
    InOrderImpl(bst_node->GetLeftChild(), ss); 
    ss << bst_node->GetContents() << " "; 
    InOrderImpl(bst_node->GetRightChild(), ss); 
    } 
} 

string BSTree::InOrder(BSTNode* bst_node) 
{ 
    ostringstream ss; 
    InOrder(bst_node, ss); 
    return ss.str(); 
} 
+0

これは機能しませんでした。残念ながら、コードは私にセグメンテーションエラーを与えます。 –

+0

最初の行にタイプミスがあるようです。 if節は '(bst_node == NULL)'でなければなりません。それは '!'ではありません。 – matz

+0

@CarlosEscobedoおそらく、別の理由でsegfaultsされています。ただし、提供されたコードは、汎用DFSトラバーサル – Pavel

0

このための私の非常に簡単 - このメソッドを参照することにより、引数としてにstringstreamを渡す:

static stringstream existingSSreference; 
string BSTree::InOrder(BSTNode* bst_node, stringstream & ss = existingSSreference) { 

    if (root_ == NULL) { 
    return ""; 
    } else { 
    if (bst_node->GetLeftChild() != NULL) { 
     InOrder(bst_node->GetLeftChild(), ss); 
    } 
    ss << bst_node->GetContents(); 
    if (bst_node->GetRightChild() != NULL) { 
     InOrder(bst_node->GetRightChild(), ss); 
    } 
    } 
    return ss.str(); 
} 

をメソッドを使用する前にストリングストリームを宣言したいかどうかを指定します。

stringstream ss; 
string myResult = bstreeObj->InOrder(bstNode, ss); 

かは、それが

string myResult = bstreeObj->InOrder(bstNode); 

これは動作するはず渡さずにそれを使用しています。関数の外側で文字列ストリームをよりよく定義し、関数を呼び出すときにそれを渡します。

EDIT、参照引数は、デフォルト値を持つことができないアジャイにより指摘したように

我々は、デフォルトとして、実際の既存のインスタンスを通過しない限り、(我々は二番目の引数を省略する可能性を保つことができるように) 。

+0

'stringstream&ss = NULL' - これもコンパイルされますか? – Ajay

+0

hm、あなたは正しいです。私は例を試すことを考えていました。私は試してみましょう、私はこの修正でそれを更新します –

1

簡単:ちょうどstringstreamが引数として渡されるユーティリティ関数を定義します。一つだけstringstreamツリー全体がダンプされた場所をインスタンス化することは、おそらくはるかに効率的に各ノードのstringstreamをインスタンス化するよりもあること

void BSTree::InOrder(BSTNode *root, std::stringstream &ss) 
{ 
    if (root == nullptr) { return; } 
    InOrder(root->GetLeftChild(), ss) 
    ss << root->GetContents() << " "; 
    InOrder(root->GetRightChild(), ss) 
} 

string BSTree::InOrder(BSTNode* bst_node) { 
    stringstream ss; 
    InOrder(bst_node, ss); 
    return ss.str(); 
} 

お知らせあなたのツリー(ユーティリティ関数をノードを取って文字列を返すものとして定義すると起こります)。

関連する問題