0

二分探索木 (BST) プログラムに取り組んでいます。割り当ての要件に従って、ユーザーはテキスト ファイルをロードしてツリーを構築します。ユーザーが望む場合は、新しいテキスト ファイルをロードして新しいツリーを作成できます。新しいテキスト ファイルをロードすると、古いツリーが破棄されます。

この要件に対応するために、新しいツリーを作成する私の方法はreadNewFile()、最初にツリーが既に存在するかどうかを確認します。存在する場合は、ツリーでデストラクタを実行します。readNewFile()ただし、グローバルにアクセスできるように、のスコープ外に存在する新しいツリーを作成する必要があります。これは可能ですか?もしそうなら、どのように説明してもらえますか?

私の縮小コード:

int main() {

    //BST
    BST rootTree;

    readNewFile(rootTree);
    readNewFile(rootTree);

    return 0;
}


void readNewFile(BST& tree) {
    ifstream inFile;
    string fileName;

    // if tree was previously filled, destroy it
    if (tree.rootPtr() != NULL) {
        tree.~BST();
        BST tree = new BST();
    }

    cout << "\nEnter file to load: ";
    cin.ignore();
    getline(cin, fileName);
    cout << "Opening file " << fileName << endl;
    inFile.open(fileName.c_str(), ios::in);

    // Populates tree... //

}

デストラクタ (BST.hpp 内):

BST::~BST() {
    destroyTree(root);
}

void BST::destroyTree(TreeNode*& treePtr) {
    if (treePtr != NULL) {
        destroyTree(treePtr->leftChildPtr);
        destroyTree(treePtr->rightChildPtr);
        delete treePtr;
    }
}

ツリーが破棄されたため、これは意味のあるセグメンテーション違反を返します。ただし、破棄されたものと同じスコープで新しいツリーを作成する方法はありBST rootTreeますか?

4

3 に答える 3

1

要件を達成する1つの方法はdel()BSTクラスでメソッドを呼び出すことです。ツリーのすべてのノードを削除するだけですが、ルートポインタは削除しません。これは、ルートノードを指すポインタです。を呼び出した後del()、新しいツリーの作成を開始できます。擬似コードは次のようになります。

// if tree was previously filled, destroy it
if (tree.rootPtr() != NULL) {
   tree.del()
}

// read the input file
// Start inserting the new nodes
于 2013-01-27T22:28:57.607 に答える
1

まず、コードの何が問題なのか。

すでに指摘したように、ツリーが破壊されると、再び使用することはできません。でデストラクタを呼び出すと、デストラクタが 2 回呼び出さBSTreadNewFile()ます。1 回目は明示的に呼び出すとき、2 回目は のローカル インスタンスmain()がスコープ外になるときです。 これは悪いです。


今それを修正する方法について:

rootTree最も簡単な方法は、 内main()でポインタとして宣言し、ポインタreadNewFile()からポインタへのポインタを引数として取得することです。 readNewFile()ポインターが指す既存のツリーを破棄し、ポインターをリセットして、作成した新しいツリーを指すようにします。単純。

ただし、より良い設計とはreadNewFile()、メンバー関数を にすることですBST。次にmain()、 new を構築し、BSTそのインスタンスのreadNewFile().

于 2013-01-27T22:29:16.307 に答える
0

自分が何をしているのかをよく理解していない限り、デストラクタを直接呼び出すことはありません。そして、それは通常、新しい配置を使用して作成されたためです。さらに、「Tt=新しいT;」TへのポインタをTに割り当てるのは意味がありません。ここでJavaismを再現していると思いますが、これら2つの言語のオブジェクトモデルはあまりにも異なります。

于 2013-01-27T22:27:01.117 に答える