Proč můj C ++ kódu nepodaří odstranit všechny uzly v mém BST?

hlasů
1

To má přejít na BST a odstranit každý uzel, včetně kořenového uzlu. Nicméně, na konci jsem si zprávu „root má před sebou ještě levý uzel.“ Proč nejsou všechny uzly odstraněn?

void deleteTree()
{   
    deleteNode(root);
    if(root->right)
        cout << root still has a right node << endl;
    if(root->left)
        cout << root still has a left node << endl;
    root = 0;

}   

void deleteNode(node *p) 
{   
    if(p->left) 
    {   
        deleteNode(p->left);
        p->left = 0;
    }   
    if(p->right) 
    {   
        deleteNode(p->right);
        p->right = 0;
    }   

    cout << Deleting node containing  << p->data << endl;
    delete p;
}   
Položena 11/02/2010 v 03:57
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
6

Váš odstraňujete pna konci ( root) a poté se pokouší získat přístup k jeho obsahu v deleteTree()případě rootuž ne poukazuje na přidělené paměti. Výsledek se bude definována.

Odpovězeno 11/02/2010 v 04:00
zdroj uživatelem

hlasů
2

Mažete root. A pak se váš kód se pokouší o přístup k paměti, kde to bylo.

Jsi dobře do nedefinované-chování pozemku.

Odpovězeno 11/02/2010 v 04:01
zdroj uživatelem

hlasů
2

Neměli byste dereference rootpoté, co ji vymazat deleteNode. Použijte ladicí nahlédnout, proč root->leftje nenulová.

Odpovězeno 11/02/2010 v 04:01
zdroj uživatelem

hlasů
2

Díváte se na root->leftpoté, co jste již odstraněny kořene, což známých či pro použití v novém přiděleného bloku.

Odpovězeno 11/02/2010 v 04:02
zdroj uživatelem

hlasů
-1

Já bych jednoduše změnit na strom sám, že by bylo snazší se s tím vyrovnat, pak:

struct Node
{
  Node(data_type data): mLeft(), mRight(), mData(data) {}
  Node(const Node& rhs): mLeft(), mRight(), mData(rhs.mData)
  {
    if (rhs.mLeft.get()) mLeft.reset(new Node(*rhs.mLeft));
    if (rhs.right.get()) mRight.reset(new Node(*rhs.mRight));
  }
  Node& operator=(Node rhs)
  {
    this->swap(rhs);
    return *this;
  }
  ~Node() { }

  void swap(Node& rhs)
  {
    using std::swap;
    swap(mLeft, rhs.mLeft);
    swap(mRight, rhs.mRight);
    swap(mData, rhs.mData);
  }

  Node* left() const { return mLeft.get(); }
  void left(std::auto_ptr<Node> node) { mLeft= node; }

  Node* right() const { return mRight.get(); }
  void right(std::auto_ptr<Node> node) { mRight = node; }

  data_type& data() { return mData; }
  const data_type& data() const { return mData; }

private:
  std::auto_ptr<Node> mLeft;
  std::auto_ptr<Node> mRight;
  data_type mData;
};

Tím, že objektově orientovaný, každý uzel je nyní zodpovědný za paměti je zpracovává. Také při použití std::auto_ptrv rozhraní je jasné, že to trvá vlastnictví.

Všimněte si, že to bylo přizpůsobené pro hluboké-kopírování, jakýkoli jiný postup vyžadující boost::shared_ptrnebo ekvivalent. A ano, std::auto_ptrnechává se tam zabývá kopírováním sám, žádná magie.

Tento design je mnohem čistší než při použití pláň C-structse všichni budou moci manipulovat s prostředky. Stále máte plný přístup k podkladová data přes přístupový ... ale dejte pozor, abyste vyvolat nedefinované chování ...

Samozřejmě stále můžete narazit dolů:

Node& node = ...
delete node.left(); // haha

Ale pokud se C ++ mohou chránit před nechtěnými otázek, ponechává otevřené dveře zlu kódu.

Odpovězeno 11/02/2010 v 14:22
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more