Miért van az, C ++ kód nem törli az összes csomópont én BST?

szavazat
1

Ez állítólag áthalad a BST és törölhet minden csomópont, köztük a gyökér. Azonban a végén, az üzenetet kapom, hogy „root még mindig van egy bal csomópontot.” Miért nem az összes csomópontot hagyni?

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;
}   
A kérdést 11/02/2010 03:57
a forrás felhasználó
Más nyelveken...                            


5 válasz

szavazat
6

Az törlünk, pa végén ( root), majd megpróbálta elérni annak tartalmát deleteTree(), ahol rootmár nem mutat memóriát. Az eredmény lesz definiálatlan.

Válaszolt 11/02/2010 04:00
a forrás felhasználó

szavazat
2

Te törlését root. És akkor a kódot próbál hozzáférni a memóriát, ahol volt.

Te is be meghatározatlan-viselkedés szárazföldön.

Válaszolt 11/02/2010 04:01
a forrás felhasználó

szavazat
2

Nem szabad dereference rootután töröljük deleteNode. Egy nyomkövető ellenőrizni, hogy miért root->leftnem üres.

Válaszolt 11/02/2010 04:01
a forrás felhasználó

szavazat
2

Nézed root->left, miután már törölt gyökér, így avalable használata egy új kijelölt blokk.

Válaszolt 11/02/2010 04:02
a forrás felhasználó

szavazat
-1

Azt egyszerűen változtatni a fa maga, hogy könnyebb lenne foglalkozni vele, akkor:

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

Azáltal, hogy az objektum-orientált, minden csomópont most felelős a memória kezeli. Továbbá, a std::auto_ptra felület világossá teszi, hogy úgy tulajdon.

Megjegyzendő, hogy ez már szabott mély másolás, más megközelítés igénylő boost::shared_ptrvagy azzal egyenértékű. És igen std::auto_ptrhagyja foglalkozó másolás magad, nincs mágikus ott.

Ez a kialakítás sokkal tisztább, mint egy sima C-structmindenki tudja manipulálni a források. Még mindig van teljes hozzáférést az alapul szolgáló adatok segítségével a tartozék ... de vigyázzon, hogy ne hivatkozhat definiált működést ...

Persze, akkor is összeomlik le:

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

De ha C ++ véd a nem kívánt kérdéseket, akkor nyitva hagyja az ajtót, hogy a rossz kódot.

Válaszolt 11/02/2010 14:22
a forrás felhasználó

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