Perché il codice C ++ mia non riescono a eliminare tutti i nodi nella mia BST?

voti
1

Questo dovrebbe attraversare una BST ed eliminare ogni nodo, tra cui il nodo principale. Tuttavia, alla fine, viene visualizzato il messaggio radice ha ancora un nodo a sinistra. Perché non vengono cancellati tutti i nodi?

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;
}   
È pubblicato 11/02/2010 alle 03:57
fonte dall'utente
In altre lingue...                            


5 risposte

voti
6

Il tuo sta eliminando palla fine ( root) e poi cercando di accedere al suo contenuto in deleteTree(), in cui rootnon sono più punti di memoria allocata. Il risultato sta per essere undefined.

Risposto il 11/02/2010 a 04:00
fonte dall'utente

voti
2

Stai eliminazione root. E poi il codice sta tentando di accedere alla memoria dove fosse.

Sei così in terra indefinita-comportamento lì.

Risposto il 11/02/2010 a 04:01
fonte dall'utente

voti
2

Non si dovrebbe risolvere il riferimento rootdopo averlo eliminato in deleteNode. Utilizzare un debugger per ispezionare il motivo per cui root->leftnon è nullo.

Risposto il 11/02/2010 a 04:01
fonte dall'utente

voti
2

Siete alla ricerca di root->leftradici dopo aver già eliminato, rendendo avalable per l'utilizzo in un nuovo blocco allocato.

Risposto il 11/02/2010 a 04:02
fonte dall'utente

voti
-1

Vorrei semplicemente cambiare l'albero stesso, sarebbe più facile da affrontare allora:

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;
};

Essendo orientato agli oggetti, ogni nodo è ora responsabile per la memoria che gestisce. Inoltre, utilizzando std::auto_ptrl'interfaccia rende chiaro che ci vuole la proprietà.

Si noti che è stato adattato per il deep-copia, qualsiasi altro approccio che richiede boost::shared_ptro equivalente. E sì std::auto_ptrti lascia trattare con la copia da soli, nessuna magia lì.

Questo disegno è molto più pulito rispetto all'utilizzo di una pianura C-structcon tutti di essere in grado di manipolare le risorse. Hai ancora pieno accesso ai dati sottostanti tramite la funzione di accesso ... ma fate attenzione a non invocare un comportamento indefinito ...

Naturalmente, è ancora possibile mandare in crash il basso:

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

Ma se C ++ può proteggere contro problemi non intenzionali, lascia la porta aperta per il codice maligno.

Risposto il 11/02/2010 a 14:22
fonte dall'utente

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