Pourquoi mon code C ++ ne parviennent pas à supprimer tous les nœuds dans mon BST?

voix
1

Ce système est censé traverser un BST et supprimer tous les noeuds, y compris le nœud racine. Cependant, à la fin, je reçois le message « racine a toujours un nœud gauche. » Pourquoi ne sont pas tous les nœuds supprimés?

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;
}   
Créé 11/02/2010 à 03:57
source utilisateur
Dans d'autres langues...                            


5 réponses

voix
6

Votre supprimons pà la fin ( root), puis tente d'accéder à son contenu deleteTree(), où rootaucun point plus à la mémoire allouée. Le résultat va être indéfini.

Créé 11/02/2010 à 04:00
source utilisateur

voix
2

Vous supprimez root. Et puis votre code tente d'accéder à la mémoire où il était.

Vous êtes bien en terre un comportement non défini là.

Créé 11/02/2010 à 04:01
source utilisateur

voix
2

Vous ne devriez pas déréférencer rootaprès avoir supprimé dans deleteNode. Utilisez un débogueur pour inspecter pourquoi root->leftest non nul.

Créé 11/02/2010 à 04:01
source utilisateur

voix
2

Vous êtes à la recherche une root->leftfois que vous avez déjà supprimé la racine, ce qui en fait avalable pour une utilisation dans un nouveau bloc alloué.

Créé 11/02/2010 à 04:02
source utilisateur

voix
-1

Je voudrais simplement changer l'arbre lui-même, il serait plus facile de traiter avec elle alors:

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

En étant orienté objet, chaque nœud est maintenant responsable de la mémoire qu'il gère. En outre, l' utilisation std::auto_ptrde l'interface, il est clair qu'il faut la propriété.

Notez qu'il a été adapté pour-copie en profondeur, toute autre approche nécessitant boost::shared_ptrou équivalent. Et oui std::auto_ptrvous laisse traiter la copie par vous - même, pas de magie là - bas.

Cette conception est beaucoup plus propre que d' utiliser une plaine C-structavec tout le monde étant en mesure de manipuler les ressources. Vous avez toujours accès aux données sous - jacentes via l'accesseur ... mais ils prennent soin de ne pas invoquer un comportement non défini ...

Bien sûr, vous pouvez planter encore vers le bas:

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

Mais si C ++ peut protéger contre les problèmes involontaires, il laisse la porte ouverte au code mal.

Créé 11/02/2010 à 14:22
source utilisateur

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