Stackoverflow अपवाद है जब BST traversing

वोट
4

मैं अपने काम में से एक के लिए एक कड़ी के आधार पर BST (बाइनरी खोज पेड़) C ++ को लागू किया है। मैं अपने पूरी कक्षा में लिखा है और सब कुछ अच्छा काम करता है, लेकिन मेरे काम मेरे लिए रन-बार प्लॉट करने के लिए पूछते हैं:

a.  A sorted list of 50000, 75000, and 100000 items
b.  A random list of 50000, 75000, and 100000 items

यह ठीक है, मैं संख्याएं डाल सकते हैं लेकिन यह भी मुझे पूछता है कॉल करने के लिए FindHeight()और CountLeaves()पेड़ पर तरीकों। मेरी समस्या यह है कि मैं का उपयोग कर दो कार्यों को क्रियान्वित किया है है recursion। जब से मैं संख्या मैं एक हो रही हो रही है की एक इतनी बड़ी सूची है stackoverflowअपवाद।

यहाँ मेरी कक्षा परिभाषा है:

template <class TItem>
class BinarySearchTree
{
public:
    struct BinarySearchTreeNode
    {
    public:
        TItem Data;
        BinarySearchTreeNode* LeftChild;
        BinarySearchTreeNode* RightChild;
    };

    BinarySearchTreeNode* RootNode;

    BinarySearchTree();
    ~BinarySearchTree();

    void InsertItem(TItem);

    void PrintTree();
    void PrintTree(BinarySearchTreeNode*);

    void DeleteTree();
    void DeleteTree(BinarySearchTreeNode*&);

    int CountLeaves();
    int CountLeaves(BinarySearchTreeNode*);

    int FindHeight();
    int FindHeight(BinarySearchTreeNode*);

    int SingleParents();
    int SingleParents(BinarySearchTreeNode*);

    TItem FindMin();
    TItem FindMin(BinarySearchTreeNode*);

    TItem FindMax();
    TItem FindMax(BinarySearchTreeNode*);
};

FindHeight () कार्यान्वयन

template <class TItem>
int BinarySearchTree<TItem>::FindHeight()
{
    return FindHeight(RootNode);
}

template <class TItem>
int BinarySearchTree<TItem>::FindHeight(BinarySearchTreeNode* Node)
{
    if(Node == NULL)
        return 0;

    return 1 + max(FindHeight(Node->LeftChild), FindHeight(Node->RightChild));
}

CountLeaves () कार्यान्वयन

template <class TItem>
int BinarySearchTree<TItem>::CountLeaves()
{
    return CountLeaves(RootNode);
}

template <class TItem>
int BinarySearchTree<TItem>::CountLeaves(BinarySearchTreeNode* Node)
{
    if(Node == NULL)
        return 0;
    else if(Node->LeftChild == NULL && Node->RightChild == NULL)
        return 1;
    else
        return CountLeaves(Node->LeftChild) + CountLeaves(Node->RightChild);
}

मैं कैसे मैं प्रत्यावर्तन के बिना दो तरीकों को लागू कर सकते के बारे में सोच की कोशिश की लेकिन मैं पूरी तरह से स्टंप्डया हूँ। क्या किसी के भी पास कोई सुझाव है?

10/11/2011 को 00:52
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


5 जवाब

वोट
1

आदेश प्रत्यावर्तन के बिना पत्ते गिनती करने के लिए, एक इटरेटर की अवधारणा का उपयोग एसटीएल आरबी पेड़ अंतर्निहित के लिए उपयोग करता है की तरह std::setऔर std::map... एक बनाएं begin()और end()आप पेड़ कि आदेश दिया पहली और आखिरी नोड (indentifies इस मामले बाएं भाग में स्थित के लिए समारोह अधिकांश नोड और उसके बाद राइट सबसे नोड)। फिर एक समारोह बनाएं जिसका नाम

BinarySearchTreeNode* increment(const BinarySearchTreeNode* current_node)

कि किसी दिए गए के लिए current_node, पेड़ में अगले नोड के लिए एक सूचक वापस आ जाएगी। काम करने के लिए इस लागू करने के लिए ध्यान रखें, आप एक अतिरिक्त आवश्यकता होगी parentअपने में सूचक nodeयात्रा प्रक्रिया में सहायता करने के लिए लिखें।

के लिए आपका एल्गोरिथ्म increment()निम्नलिखित कुछ ऐसा दिखाई देगा:

  1. अगर वहाँ वर्तमान नोड के लिए एक सही बच्चा है देखने के लिए जाँच करें।
  2. अगर वहाँ एक सही-बच्चा है, थोड़ी देर के पाश का उपयोग करें कि सही सबट्री का सबसे बाईं ओर नोड खोजने के लिए। यह "अगला" नोड हो जाएगा। अन्यथा कदम # 3 जाओ।
  3. अगर वहाँ वर्तमान नोड पर कोई अधिकार नहीं-बच्चा है, तो अगर वर्तमान नोड अपनी मूल नोड के बाएं बच्चा है देखने के लिए जाँच।
  4. तो कदम # 3 सत्य है, तभी "अगला" नोड माता पिता नोड है, तो आप इस बिंदु पर बंद कर सकते हैं, नहीं तो अगले कदम जाना है।
  5. तो चरण # 3 झूठा था, तो वर्तमान नोड माता पिता के दाएँ बच्चा है। इस प्रकार आप जब तक आप एक नोड कि अपनी मूल नोड के एक बाएँ बच्चा है के पार चलो थोड़ी देर के पाश का उपयोग कर अगले माता पिता नोड के लिए ऊपर जा रहा रखने के लिए की आवश्यकता होगी। इस बाएं चाइल्ड नोड के माता-पिता तो "अगला" नोड हो जाएगा, और आप रोक सकते हैं।
  6. अंत में, जड़ करने के लिए कदम # 5 रिटर्न आप, तो वर्तमान नोड पेड़ में पिछले नोड है, और इटरेटर पेड़ के अंत तक पहुँच गया है।

अंत में आप एक की आवश्यकता होगी bool leaf(const BinarySearchTreeNode* current_node)समारोह एक दिया नोड एक पत्ता नोड है कि क्या परीक्षण कर सकते हैं। इस प्रकार आप काउंटर समारोह बस हालांकि पेड़ पुनरावृति और सभी पत्र-गांठ पा सकते हैं, एक अंतिम गिनती लौटने इसके पूरा होने पर।

आप प्रत्यावर्तन के बिना एक असंतुलित पेड़ की अधिकतम गहराई को मापने के लिए चाहते हैं, तो आप अपने पेड़ के दशक में होगा insert()समारोह, गहराई है कि एक नोड पर डाला गया था का ट्रैक रखने की जरूरत है। यह बस अपने में एक चर हो सकता है nodeप्रकार जब नोड पेड़ में डाला जाता है सेट है। तो आप तीन के माध्यम से पुनरावृति, और एक पत्ता नोड की अधिकतम गहराई पा सकते हैं।

Btw, इस विधि की जटिलता दुर्भाग्य हे (एन) होने जा रहा है ... हे (लॉग एन) के रूप में के रूप में अच्छा के पास कहीं भी नहीं।

10/11/2011 को 01:01
का स्रोत उपयोगकर्ता

वोट
3

100,000 नोड्स के साथ एक पेड़ पर प्रत्यावर्तन एक समस्या अगर यह संतुलित किया जाता है नहीं होना चाहिए। गहराई केवल शायद 17 है, जो पता चला कार्यान्वयन में बहुत ज्यादा ढेर का उपयोग नहीं करेगा। (log2(100,000) = 16.61)। तो यह है कि शायद कोड है कि पेड़ बनाने जा रहा है इसे सही ढंग से संतुलन नहीं है लगता है।

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

वोट
1

हो सकता है आप इस गणना करने के लिए, जबकि डालने कर की जरूरत है। नोड्स की ऊंचाइयों स्टोर, यानी नोड वस्तु में ऊंचाई की तरह एक पूर्णांक क्षेत्र जोड़ें। इसके अलावा काउंटर ऊंचाई पेड़ के लिए पत्तियों की है। आप एक नोड डालते हैं तो, अगर अपनी मूल है (था) एक पत्ता, पत्ती गिनती नहीं करता है परिवर्तन, लेकिन यदि नहीं, 1. द्वारा पत्ती संख्या में वृद्धि भी नए नोड की ऊंचाई माता पिता की ऊंचाई + 1 है, कि इसलिए यदि अधिक से अधिक है पेड़ की वर्तमान ऊंचाई से है, तो यह अद्यतन करें। यह एक होमवर्क, तो मैं वास्तविक कोड के साथ मदद के अभ्यस्त

10/11/2011 को 01:05
का स्रोत उपयोगकर्ता

वोट
2

मैंने पाया यह पेज बहुत शिक्षाप्रद है क्योंकि यह एक समारोह यात्रा का उपयोग करता है एक के लिए प्रत्यावर्तन का उपयोग करता है परिवर्तित करने के यांत्रिकी के बारे में बात करती है।

यह कोड दिखा रूप में अच्छी तरह उदाहरण है।

10/11/2011 को 01:06
का स्रोत उपयोगकर्ता

वोट
1

कभी-कभी आपके पेड़ संतुलित करें। अपने पेड़ FindHeight (पर stackoverflow) हो रही है, तो इसका मतलब है कि आपके पेड़ है जिस तरह से असंतुलित। अगर पेड़ संतुलित है यह केवल 100000 तत्वों के लिए के बारे में 20 नोड्स की गहराई होनी चाहिए।

फिर से संतुलन असंतुलित द्विआधारी पेड़ का सबसे आसान (लेकिन काफी धीमी गति से) जिस तरह की एक सरणी आवंटित करने के लिए है TItem, काफी बड़ा पेड़ में डेटा के सभी पकड़ करने के लिए क्रमबद्ध क्रम में इसे में अपने सभी डेटा के डालें, और हटाने के सभी नोड्स के । तब रिकर्सिवली सरणी से पेड़ के पुनर्निर्माण। जड़ बीच में नोड है। root->leftबायां भाग के बीच है, root->rightसही आधा के बीच है। रिकर्सिवली दोहराएँ। यह संतुलित करने के लिए सबसे आसान तरीका है, लेकिन यह slowish है और अस्थायी रूप से स्मृति के बहुत सारे लेता है। दूसरी ओर, आप केवल जब तुम पता लगा कि पेड़ है यह करने के लिए है बहुत असंतुलित, (डालने पर गहराई 100 से अधिक है)।

अन्य (बेहतर) विकल्प आवेषण के दौरान संतुलन के लिए है। यह करने के लिए सबसे सहज तरीका है कि कितने नोड्स वर्तमान नोड के नीचे हैं का ट्रैक रखने के लिए है। अगर सही बच्चे छोड़ दिया बच्चे के रूप में दो बार के रूप में कई "बच्चा" नोड्स से भी अधिक है, छोड़ दिया "रोटेट करें"। और इसके विपरीत। वहाँ कैसे पेड़ सब इंटरनेट पर घूमता है क्या करने के लिए पर instrcutions है। यह थोड़ी धीमी आवेषण करता है, लेकिन उसके बाद आप सामयिक बड़े पैमाने पर स्टालों कि पहला विकल्प बनाता है नहीं है। दूसरी ओर, आप लगातार के रूप में आप घूमता करते हैं, जो तुच्छ नहीं है "बच्चों" मायने रखता है के सभी अपडेट करना होगा।

10/11/2011 को 01:08
का स्रोत उपयोगकर्ता

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