क्यों मेरी सी ++ कोड मेरी BST में सभी नोड्स को नष्ट करने में विफल रहा है?

वोट
1

यह एक BST पार और प्रत्येक नोड हटाने के लिए, रूट नोड सहित माना जाता है। हालांकि, अंत में, मैं संदेश रूट अभी भी एक बाईं नोड है। मिल क्यों सभी नोड्स को नहीं हटाया जाता?

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;
}   
11/02/2010 को 03:57
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


5 जवाब

वोट
6

आपका हटा रहे हैं pअंत (कम root) और फिर में इस सामग्री को एक्सेस करने की कोशिश कर deleteTree(), जहां rootआबंटित स्मृति को अब अंक। परिणाम अपरिभाषित होने जा रही है।

11/02/2010 को 04:00
का स्रोत उपयोगकर्ता

वोट
2

आप हटा रहे हैं root। और फिर अपने कोड स्मृति का उपयोग करने के लिए जहां यह था कोशिश कर रहा है।

आप अपरिभाषित-व्यवहार भूमि में अच्छी तरह से कर रहे हैं।

11/02/2010 को 04:01
का स्रोत उपयोगकर्ता

वोट
2

आप भिन्नता नहीं करना चाहिए rootके बाद आप में हटा deleteNode। निरीक्षण करने के लिए क्यों एक डिबगर का उपयोग root->leftगैर-शून्य है।

11/02/2010 को 04:01
का स्रोत उपयोगकर्ता

वोट
2

आप देख रहे हैं root->leftके बाद आप पहले से ही हटा देने के बाद जड़, यह एक नई आवंटित ब्लॉक में उपयोग के लिए आते बना रही है।

11/02/2010 को 04:02
का स्रोत उपयोगकर्ता

वोट
-1

मैं बस पेड़ ही बदल जाएगा, यह तो इससे निपटने के लिए आसान होगा:

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

वस्तु उन्मुख किया जा रहा से, प्रत्येक नोड अब स्मृति यह संभालती के लिए जिम्मेदार है। इसके अलावा, का उपयोग करते हुए std::auto_ptrइंटरफ़ेस में यह स्पष्ट है कि यह स्वामित्व लेता है बनाता है।

ध्यान दें कि यह गहरे प्रतिलिपि बनाने के लिए अनुरूप किया गया है, किसी भी अन्य दृष्टिकोण की आवश्यकता होती है boost::shared_ptrया समकक्ष। और हाँ std::auto_ptrआप खुद ही नकल के साथ काम कर, कोई जादू वहाँ छोड़ देता है।

इस डिजाइन एक सादे का उपयोग करने से अधिक स्वच्छ है C-structहर किसी के संसाधनों में हेरफेर करने में सक्षम होने के साथ। तुम अब भी एक्सेसर के माध्यम से अंतर्निहित डेटा पर पहुंच सकते हैं ... लेकिन वे अपरिभाषित व्यवहार आह्वान करने के लिए नहीं ख्याल रखना ...

बेशक, आप अभी भी कुचल सकता है नीचे:

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

लेकिन अगर सी ++ अनायास ही मुद्दों के खिलाफ की रक्षा कर सकते हैं, यह दरवाजा बुराई कोड के लिए खुला छोड़ देता है।

11/02/2010 को 14:22
का स्रोत उपयोगकर्ता

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