2009-05-18 49 views
2

C++のバイナリ検索ツリーの実装に関する質問があります。 ここに質問がありますバイナリ検索ツリー

整数を格納する単純な(テンプレート化されていない)BSTを実装します。 Insert、Remove、inOrderのトラバーサル、preOrderのトラバーサル、postOrderのトラバーサルを提供します。

ツリーを処理するための再帰ルーチンを使用します。

ノードの処理には、ノードの内容(この場合はノードに格納されている整数)が印刷されます。

データはテストファイルから取得する必要があります。メインプログラムは、データファイルを開いてツリーに挿入し、他のツリー操作を示す必要があります。

この練習のポイントは、BSTを理解していることを実証することです。それを船に乗せて求められていない操作をする必要はありません。

私はこれまでにヘッダファイルを作成しただけです。私は正しい方向に向かっていると誰も見てみると助言してもらえますか?

using namespace std; 
#ifndef BSTNODE_H 
#define BSTNODE_H 
class BSTNode 
{ 
    private: 
    //Defines the 'node' structure 
    struct tree_node 
    { 
    tree_node *left; // left subtree has smaller elements 
    tree_node *right; // right subtree has larger elements 
    int m_data; 
    }; 
    //root * r; 
    public: 
     //The Constructor 
     BSTNode(); 
     //The Destructor 
     ~BSTNode(); 
     //Inserts a value into a BST, public function 
     void insert(const m_data & d); 
     //Removes a value from a BST, public function 
     void remove(const m_data & d); 
     //isEmpty function, public function 
     bool isEmpty(); 
     BSTNode getData(); 
     void inOrder(const m_data & d); 
     void preOrder(const m_data & d); 
     void postOrder(const m_data & d); 
}; 
#endif 

次は、BSTNode.cppファイルを作成する必要があります。 [email protected]にメールであなたの応答を感謝してください前もってありがとうございます。

+0

トラバーサル関数をイテレータとして実装する必要がありますか?私は答えとしてこれを追加するのに十分なC++のコンベンションを知らない。 – CookieOfFortune

+1

入れない:using namespace std;ヘッダーファイルに追加します。 –

答えて

3

あなたはtypedefには、さまざまな方法で使用しているタイプm_dataを忘れてしまったように見える、と私はあなたが別のtree_node構造体をしたい理由を理解していない(というよりも、クラス自体を使用して?)も、なぜgetDataがすべきintではなくBSTNodeを返します。

3
//Inserts a value into a BST, public function 
    void insert(const m_data & d); 
    //Removes a value from a BST, public function 
    void remove(const m_data & d); 
    //isEmpty function, public function 
    bool isEmpty(); 
    BSTNode getData(); 
    void inOrder(const m_data & d); 
    void preOrder(const m_data & d); 
    void postOrder(const m_data & d); 

m_dataはメンバーであり、型ではありません。ここでintを使用する必要があります。また、あなたのノードはtree_nodeなので、外部クラスはツリー全体を表すはずです(つまり、BSTreeはBSTNodeではありません)。

また、 'using namespace std;'ヘッダーが含まれていないものは、それを強制的にオプトアウトする方法がないので、ヘッダーでは悪いです。あなたがそれを使うつもりなら、.cppファイルに保管することをお勧めします。

+0

'namespace std;を使用する必要はないようです。ヘッダーには - そこから私が見ることができるものは何もありません。 –

1

これはBSTに関する古典的な質問です。データ構造の良い本であれば、コード全体が得られます。次のページには、C++ http://cslibrary.stanford.edu/110/BinaryTrees.htmlのコード例が含まれています。

トラバーサル関数はBSTクラス自体の一部であってはならず、実際にはBSTNodeは左/右ノードポインタを公開する必要があります。呼び出し側アプリケーションはそれを特定の方法で呼び出す必要があります。または、コールバック関数を使用して、クラス内でトラバーサルコードを提供してください。こうすれば、はるかにクリーンになります。

1

カップルの事 - 他の人が指摘したように、あなたが

void insert(const int & d); 
//Removes a value from a BST, public function 
void remove(const int & d); 
//isEmpty function, public function 
bool isEmpty(); 
BSTNode getData(); 
void inOrder(const int & d); 
void preOrder(const int & d); 
void postOrder(const int & d); 

他のものを使用する必要がありますが、あなたのルートノードをコメントアウトしているということです。間違って定義しましたが、クラスにルートノードを含める必要があります。正しい定義は、前に指摘したように、名前空間stdを使用して

を削除し、また

tree_node *root; 

だろう。

ヘッダーファイルから、代わりに実装ファイルに入れてください。

これは私が今見ることのできるすべてです。

1

もう1つの問題は、指定されたクラスがネストされた型とメソッドを宣言し、メンバーデータを宣言しないことです。


イテレーターを使用してトラバーサル機能を宣言することができます。 preorderメソッドはインターレーターを返します。これはノードに参照解除することができます。または、プリオーダーシーケンスの次のノードをポイントするインクリメントです。

コールバックを使用してトラバーサル機能を宣言することもできます。つまり、呼び出し元がコールバックインスタンスをプリオーダメソッドに渡し、プリオーダメソッドがツリーをトラバースし、各ノードのコールバックメソッドを呼び出します。コールバックメソッドはノードより具体的にはノードデータ)をパラメータとして返すことができ、コールバックがトラバースを異常終了させようとしていることを明らかにするブール値を返すことがあります。

1

検索方法も追加します。

bool search(int whatIlookfor); 

またはより良い

tree_node* search(int whatIlookfor); 

また、安全な場所にtree_node *rootを保ちます。些細

2

何か:一般に

tree_node *left; // left subtree has smaller elements 

、左サブツリーも同じ要素を含みます。あなたの例では構造体型の左と右のポインタを使用して

+0

は実装に依存しますが、バイナリ検索ツリーに重複したノードを避けるためにすぐにそれらを含めることはできません。 –

+0

これは本当です - 実装によって異なります。しかし、私は、彼がまだ存在していなければ、OPが同じ要素を挿入することに懸念すべきであることを指摘したいだけでした。 – Donotalo

1
  • 、柔軟性を制限するだろう - 私はあなたのBSTを取り、根の左の子にトラバースし、この新しいサブツリーに対して操作を呼び出したいとします。ポインタは構造体型であるため、私はできません。 BSTNode型の両方のポインタを使用することをお勧めします。

    BSTNode *left;

    BSTNode *right;

    また、これはあなたの根本的な問題を解決するだろう(明示的なルートポインタは必要ありません)、あなたがメインで、あなたのオブジェクトを参照するために使用するポインタ以来、とにかくルートを指されます。

  • トラバーサル関数は、本質的にツリー全体を走査し、すべてのデータ項目を印刷するときに引数を必要とすべきではありません。データ項目は、既にTrueStarによって指摘されているように、その位置を検索するために別の検索メンバー関数に渡すことができます。

  • 私も(DeleteNodeCaseB(int data)が時間内からDeleteNodeCaseA(int data)を呼び出して、もう一度でしょう)あなたのパブリックメンバ関数の複雑さを軽減するために、いくつかのプライベートメンバ関数を示唆 -

    BSTNode * setleft(int data);

    BSTNode * setright(int data);

    void DeleteNodeCaseA(int data)/*いずれかまたは左右の子供の両方が存在しない*/

    void DeleteNodeCaseB(int data)/*左と右の両方の子供を持っている*/

1

あなたがC++を使っているので、あなたは、いくつかの標準ライブラリを使用するのではなく、すべてを自分で実装しようとして検討する必要がありますか? STLライブラリには赤黒のツリーが付いていますので、アプリケーションに適しています。バイナリツリーは、ループリストまたはリンクリストに縮退することができます。

PS:もちろん、これはあなたが宿題をしていないことを前提としています。