17

के साथ एक बाइनरी ट्री पर इटरेट करना क्या ओ (1) सहायक अंतरिक्ष (एक स्टैक, कतार, इत्यादि का उपयोग करके डब्ल्यू/ओ) में बाइनरी पेड़ को फिर से शुरू करना संभव है, या यह साबित हुआ है असंभव? यदि यह संभव है, तो यह कैसे किया जा सकता है?ओ (1) सहायक अंतरिक्ष

संपादित करें: यदि माता-पिता नोड्स के पॉइंटर्स हैं तो यह संभव है कि मुझे यह संभव हो गया है और मुझे नहीं पता था कि यह किया जा सकता है, लेकिन इस पर निर्भर करता है कि आप इसे कैसे देखते हैं, यह हो सकता है (एन) सहायक अंतरिक्ष। इसके अलावा, मेरे व्यावहारिक उपयोग मामले में, पैरेंट नोड्स के लिए कोई संकेतक नहीं हैं। अब से, कृपया उत्तर देने पर इसे मान लें।

+2

मैं माता-पिता को ओ (एन) सहायक स्थान के रूप में लिंक मानता हूं। आपको अपने बाइनरी पेड़ का स्पष्ट रूप से उल्लेख करने के लिए अपने प्रश्न को संपादित करना चाहिए, ऐसी संपत्ति नहीं है। –

+1

आपके माता-पिता नोड्स के पॉइंटर्स कैसे नहीं हो सकते हैं? आप अपने पेड़ पर बिना उनके बिना कैसे पुन: प्रयास कर सकते हैं? क्या वह ढेर आ रहा है? संतुलन करने के लिए आपको माता-पिता के पॉइंटर्स की आवश्यकता होगी। –

उत्तर

2

पेड़ संरक्षित करने के साथ ही हे (1) अंतरिक्ष यह संभव है अगर ...

  • प्रत्येक नोड एक निश्चित आकार का उपयोग करें।
  • पूरे वृक्ष स्मृति का एक सन्निहित हिस्सा (यानी एक सरणी)
  • आप पेड़ से अधिक पुनरावृति नहीं है में है, तो आप बस सरणी

से अधिक पुनरावृति या आप पेड़ के रूप में नष्ट करता है, तो आप इसे संसाधित ...:

  • @Svante इस विचार के साथ आया था, लेकिन मैं कैसे एक छोटे पर विस्तार करने के लिए, एक विनाशकारी दृष्टिकोण का उपयोग करना चाहता था।
  • कैसे? आप पेड़ में सबसे अधिक पत्ता नोड लेना जारी रख सकते हैं ((;;) नोड = नोड-> बाएं इत्यादि ..., फिर इसे संसाधित करें, फिर इसे हटा दें। यदि पेड़ में बाएं नोड नहीं है पत्ता नोड है, तो आप को संसाधित करने और सही नोड के सबसे छोड़ दिया पत्ती नोड को हटा दें। एक सही नोड कोई संतान नहीं है, तो आप को संसाधित करने और इसे हटा दें।

तरीके है कि यह काम नहीं होगा ...

यदि आप रिकर्सन का उपयोग करते हैं तो आप एक स्टैक का उपयोग करेंगे। कुछ एल्गोरिदम (इस समस्या के लिए नहीं) के लिए पूंछ रिकर्सन आपको रिकर्सन का उपयोग करने और ओ (1) स्पेस रखने की अनुमति देगा, लेकिन चूंकि किसी भी विशेष नोड में कई बच्चे हो सकते हैं, और इसलिए वहाँ है रिकर्सिव कॉल के बाद करने के लिए काम करते हैं, ओ (1) अंतरिक्ष पूंछ रिकर्सन संभव नहीं है।

आप एक समय में समस्या को 1 स्तर से निपटने का प्रयास कर सकते हैं, लेकिन सहायक (निहित या स्पष्ट) स्थान के बिना मनमानी स्तर के नोड्स तक पहुंचने का कोई तरीका नहीं है। उदाहरण के लिए आप जिस नोड को चाहते हैं उसे ढूंढने के लिए पुन: देखभाल कर सकते हैं, लेकिन फिर यह अनुमानित स्टैक स्पेस लेता है। या आप अपने सभी नोड्स को प्रति स्तर एक और डेटा संरचना में स्टोर कर सकते हैं, लेकिन इसमें अतिरिक्त जगह भी होती है।

+2

आप गलत हैं, Knuth TAOCP I.2.3।1 अभ्यास 21 मूल पेड़ को नष्ट किए बिना ओ (1) अंतरिक्ष में पेड़ के ट्रैवर्सल के लिए कम से कम तीन एल्गोरिदम को संदर्भित करता है (हालांकि वे इसे अस्थायी रूप से जगह में संशोधित करते हैं)। –

+0

@nobody_: मैंने उन मामलों में नहीं लिया जहां आपको पेड़ को संशोधित करने की अनुमति है। लेकिन मैंने 2 उदाहरण दिए, तो निश्चित रूप से इसमें कुछ है :) वैसे भी मैंने अमान्य हिस्सों को निकालने के लिए अपना जवाब संशोधित किया। –

+0

टीएओसीपी के बिना उन लोगों के लिए, @ एंटोनटाइकी मॉरिस पेड़ ट्रैवर्सल एल्गोरिदम का जिक्र कर रहा है, जो ओ (एन) समय और ओ (1) सहायक अंतरिक्ष में चलता है। यह पृष्ठ सहायता कर सकता है: http://stackoverflow.com/questions/5502916/explain-morris-inorder-tree-traversal-without-using-stacks-or-recursion। इसके अलावा, किसी ने नीचे प्री-ऑर्डर मॉरिस एल्गोरिदम पोस्ट किया है। –

6

यदि आपके पास प्रत्येक बच्चे में माता-पिता का लिंक है तो यह संभव है। जब आप बच्चे का सामना करते हैं, तो बाएं उपट्री पर जाएं। बैक अप आने पर यह देखने के लिए जांचें कि क्या आप अपने माता-पिता के बाएं बच्चे हैं या नहीं। यदि ऐसा है, तो सही उपट्री पर जाएं। अन्यथा, जब तक आप बाएं बच्चे न हों तब तक ऊपर जायें जब तक कि आप पेड़ की जड़ को हिट न करें।

इस उदाहरण में ढेर का आकार स्थिर रहता है, इसलिए कोई अतिरिक्त स्मृति खपत नहीं होती है। बेशक, जैसा कि मेहर्डद ने बताया, माता-पिता के लिंक को ओ (एन) स्थान माना जा सकता है, लेकिन यह पेड़ की संपत्ति से अधिक है, यह एल्गोरिदम की संपत्ति है।

यदि आपको उस पेड़ को पार करने के क्रम में कोई परवाह नहीं है, तो आप नोड्स पर एक अभिन्न मैपिंग असाइन कर सकते हैं जहां रूट 1 है, रूट के बच्चे 2 और 3 हैं, उनमें से बच्चे हैं 4, 5, 6, 7, इत्यादि। फिर आप पेड़ की प्रत्येक पंक्ति के माध्यम से काउंटर को बढ़ाकर और उस नोड को इसके संख्यात्मक मूल्य से एक्सेस करके लूप करते हैं। आप उच्चतम संभावित बच्चे तत्व का ट्रैक रख सकते हैं और जब आपका काउंटर गुजरता है तो लूप को रोक सकते हैं। समय-समय पर, यह एक अत्यंत अक्षम अक्षम एल्गोरिदम है, लेकिन मुझे लगता है कि यह ओ (1) स्थान लेता है।

(मैं ढेर से नंबर के विचार उधार लिया था। आप नोड एन है, तो आप 2N पर बच्चों और 2N +1 पा सकते हैं। आप एक बच्चे के माता-पिता को खोजने के लिए इस नंबर से पीछे की ओर काम कर सकते हैं।)

यहाँ सी सूचना में कार्रवाई में इस एल्गोरिथ्म का एक उदाहरण है कि वहाँ पेड़ के निर्माण के लिए छोड़कर कोई malloc के हैं, और कोई पुनरावर्ती कार्य हैं कि जिसका अर्थ है कि ढेर निरंतर अंतरिक्ष लेता है:

#include <stdio.h> 
#include <stdlib.h> 

typedef struct tree 
{ 
    int value; 
    struct tree *left, *right; 
} tree; 

tree *maketree(int value, tree *left, tree *right) 
{ 
    tree *ret = malloc(sizeof(tree)); 
    ret->value = value; 
    ret->left = left; 
    ret->right = right; 
    return ret; 
} 

int nextstep(int current, int desired) 
{ 
    while (desired > 2*current+1) 
     desired /= 2; 

    return desired % 2; 
} 

tree *seek(tree *root, int desired) 
{ 
    int currentid; currentid = 1; 

    while (currentid != desired) 
    { 
     if (nextstep(currentid, desired)) 
    if (root->right) 
     { 
     currentid = 2*currentid+1; 
     root = root->right; 
     } 
    else 
     return NULL; 
     else 
    if (root->left) 
     { 
     currentid = 2*currentid; 
     root = root->left; 
     } 
    else 
     return NULL; 
    } 
    return root; 
} 


void traverse(tree *root) 
{ 
    int counter; counter = 1; /* main loop counter */ 

    /* next = maximum id of next child; if we pass this, we're done */ 
    int next; next = 1; 

    tree *current; 

    while (next >= counter) 
    { 
     current = seek(root, counter); 
     if (current) 
     { 
      if (current->left || current->right) 
       next = 2*counter+1; 

      /* printing to show we've been here */ 
      printf("%i\n", current->value); 
     } 
     counter++; 
    } 
} 

int main() 
{ 
    tree *root1 = 
    maketree(1, maketree(2, maketree(3, NULL, NULL), 
          maketree(4, NULL, NULL)), 
       maketree(5, maketree(6, NULL, NULL), 
          maketree(7, NULL, NULL))); 

    tree *root2 = 
     maketree(1, maketree(2, maketree(3, 
      maketree(4, NULL, NULL), NULL), NULL), NULL); 

    tree *root3 = 
     maketree(1, NULL, maketree(2, NULL, maketree(3, NULL, 
      maketree(4, NULL, NULL)))); 

    printf("doing root1:\n"); 
    traverse(root1); 

    printf("\ndoing root2:\n"); 
    traverse(root2); 

    printf("\ndoing root3:\n"); 
    traverse(root3); 
} 

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

+0

ब्रायन, संख्या का प्रत्येक बिट आपको दिखाएगा कि आप किस दिशा में जाएंगे। –

+0

लेकिन अतिरिक्त जगह का उपयोग किए बिना उदाहरण के लिए आप नोड # 7 तक कैसे पहुंचेंगे? इस तरह के नोड को खोजने के लिए रिकर्स करने के लिए अंतरिक्ष ले जाएगा, और यदि आपने अन्य नोड्स को किसी अन्य डेटा स्ट्रक्चर में संग्रहीत किया है जो अतिरिक्त स्थान भी लगाएगा। –

+0

@ ब्रायन आप 1 को घटा सकते हैं और 2 से विभाजित कर सकते हैं यह देखने के लिए कि 3 7 है। इसी तरह, आप 1 को 3 से घटा सकते हैं और यह देखने के लिए कि 2 है 3 माता-पिता। इसलिए, आपको केवल एक लूप चाहिए जो वर्तमान नोड से वांछित नोड के पथ में अगले चरण की गणना करेगा। –

1

यदि नोड्स के माता-पिता के पॉइंटर्स हैं तो आप इसे प्राप्त कर सकते हैं। जब आप पेड़ का बैक अप लेते हैं (पैरेंट प्वाइंटर्स का उपयोग करके) आप उस नोड को भी पास करते हैं जिससे आप आ रहे हैं। यदि आप जिस नोड से आ रहे हैं वह उस नोड का बायां बच्चा है जिसे आप अभी कर रहे हैं, तो आप सही बच्चे को पार करते हैं। अन्यथा आप इसके माता-पिता के पास वापस चले जाते हैं।

प्रश्न में संपादन के जवाब में संपादित करें: यदि आप पूरे पेड़ के माध्यम से फिर से शुरू करना चाहते हैं, तो यह संभव नहीं है। पेड़ को वापस चढ़ने के लिए आपको यह जानने की जरूरत है कि कहां जाना है। हालांकि, अगर आप पेड़ के नीचे एकल पथ के माध्यम से फिर से शुरू करना चाहते हैं तो यह ओ (1) अतिरिक्त स्थान में प्राप्त किया जा सकता है। थोड़ी देर लूप का उपयोग करके पेड़ को बस फिर से चालू करें, वर्तमान नोड को एक पॉइंटर रखें। पेड़ को तब तक जारी रखें जब तक कि आप नोड को न ढूंढें या पत्ती नोड दबाएं।

संपादित करें: यहाँ पहले एल्गोरिथ्म के लिए कोड है (iterate_constant_space() फ़ंक्शन की जाँच और मानक पुनरावृति() फ़ंक्शन के परिणामों की तुलना):

#include <cstdio> 
#include <string> 
using namespace std; 

/* Implementation of a binary search tree. Nodes are ordered by key, but also 
* store some data. 
*/ 
struct BinarySearchTree { 
    int key;  // they key by which nodes are ordered 
    string data; // the data stored in nodes 
    BinarySearchTree *parent, *left, *right; // parent, left and right subtrees 

    /* Initialise the root 
    */ 
    BinarySearchTree(int k, string d, BinarySearchTree *p = NULL) 
    : key(k), data(d), parent(p), left(NULL), right(NULL) {}; 
    /* Insert some data 
    */ 
    void insert(int k, string d); 
    /* Searches for a node with the given key. Returns the corresponding data 
    * if found, otherwise returns None.""" 
    */ 
    string search(int k); 
    void iterate(); 
    void iterate_constant_space(); 
    void visit(); 
}; 

void BinarySearchTree::insert(int k, string d) { 
    if (k <= key) { // Insert into left subtree 
    if (left == NULL) 
     // Left subtree doesn't exist yet, create it 
     left = new BinarySearchTree(k, d, this); 
    else 
     // Left subtree exists, insert into it 
     left->insert(k, d); 
    } else { // Insert into right subtree, similar to above 
    if (right == NULL) 
     right = new BinarySearchTree(k, d, this); 
    else 
     right->insert(k, d); 
    } 
} 

string BinarySearchTree::search(int k) { 
    if (k == key) // Key is in this node 
    return data; 
    else if (k < key && left) // Key would be in left subtree, which exists 
    return left->search(k); // Recursive search 
    else if (k > key && right) 
    return right->search(k); 
    return "NULL"; 
} 

void BinarySearchTree::visit() { 
    printf("Visiting node %d storing data %s\n", key, data.c_str()); 
} 

void BinarySearchTree::iterate() { 
    visit(); 
    if (left) left->iterate(); 
    if (right) right->iterate(); 
} 

void BinarySearchTree::iterate_constant_space() { 
    BinarySearchTree *current = this, *from = NULL; 
    current->visit(); 
    while (current != this || from == NULL) { 
    while (current->left) { 
     current = current->left; 
     current->visit(); 
    } 
    if (current->right) { 
     current = current->right; 
     current->visit(); 
     continue; 
    } 
    from = current; 
    current = current->parent; 
    if (from == current->left) { 
     current = current->right; 
     current->visit(); 
    } else { 
     while (from != current->left && current != this) { 
     from = current; 
     current = current->parent; 
     } 
     if (current == this && from == current->left && current->right) { 
     current = current->right; 
     current->visit(); 
     } 
    } 
    } 
} 

int main() { 
    BinarySearchTree tree(5, "five"); 
    tree.insert(7, "seven"); 
    tree.insert(9, "nine"); 
    tree.insert(1, "one"); 
    tree.insert(2, "two"); 
    printf("%s\n", tree.search(3).c_str()); 
    printf("%s\n", tree.search(1).c_str()); 
    printf("%s\n", tree.search(9).c_str()); 
    // Duplicate keys produce unexpected results 
    tree.insert(7, "second seven"); 
    printf("%s\n", tree.search(7).c_str()); 
    printf("Normal iteration:\n"); 
    tree.iterate(); 
    printf("Constant space iteration:\n"); 
    tree.iterate_constant_space(); 
} 
+0

"जब आप पेड़ का बैक अप लेते हैं" ... आप पेड़ में प्रत्येक नोड के नीचे कैसे जाते हैं? –

+0

वर्तमान = रूट; जबकि वर्तमान-> बायां मौजूद है: वर्तमान = वर्तमान-> बाएं – marcog

+0

@marcog: हाँ आप निश्चित रूप से एक नोड तक पहुंच सकते हैं .... लेकिन मैंने कहा कि पेड़ में प्रत्येक नोड के नीचे आप कैसे जाते हैं? –

-1

मुझे लगता है कि वहाँ कोई रास्ता नहीं आप ऐसा करते हैं सकता है, क्योंकि आपको किसी भी तरह से नोड्स को ढूंढना चाहिए जहां आपने पथ में छोड़ा था और यह पहचानने के लिए कि आपको हमेशा ओ (ऊंचाई) स्थान की आवश्यकता है।

4

आप इसे हर तरह के पत्ते को अनलिंक कर सकते हैं, जब आप जाते हैं। यह कुछ स्थितियों में लागू हो सकता है, यानी जब आपको पेड़ की आवश्यकता नहीं होती है।

विस्तार से, आप एक और बाइनरी पेड़ बना सकते हैं क्योंकि आप पहले को नष्ट कर देते हैं। आपको यह सुनिश्चित करने के लिए कुछ मेमोरी माइक्रोमैनेजमेंट की आवश्यकता होगी कि चोटी की स्मृति कभी भी मूल पेड़ के आकार से अधिक न हो और शायद थोड़ा स्थिर हो। हालांकि, यह शायद कुछ कंप्यूटिंग ओवरहेड होगा, हालांकि।

संपादित करें: एक तरीका है! अस्थायी रूप से उन्हें उलटकर पेड़ को वापस करने के तरीके को प्रकाश देने के लिए आप स्वयं नोड्स का उपयोग कर सकते हैं।जब आप किसी नोड पर जाते हैं, तो आप अपने left-child पॉइंटर को अपने माता-पिता को इंगित करते हैं, इसके right-child पॉइंटर को पिछली बार जब आपने अपने पथ पर सही मोड़ लिया था (जो इस पल में माता-पिता के right-child पॉइंटर में पाया जाता है), और इसकी असली स्टोर करें बच्चों को या तो अब-अनावश्यक माता-पिता के right-child पॉइंटर या आपके ट्रैवर्सल स्टेट रेस में। अगले दौरे वाले बच्चों के left-child सूचक। आपको कुछ पॉइंटर्स को वर्तमान नोड और इसके आसपास के क्षेत्र में रखने की आवश्यकता है, लेकिन कुछ भी "गैर-स्थानीय" नहीं है। जैसे ही आप पेड़ का बैक अप लेते हैं, आप प्रक्रिया को उलट देते हैं।

मुझे आशा है कि मैं इसे किसी भी तरह स्पष्ट कर सकता हूं; यह सिर्फ एक मोटा स्केच है। आपको इसे कहीं भी देखना होगा (मुझे यकीन है कि यह आर्ट ऑफ कंप्यूटर प्रोग्रामिंग में कहीं भी उल्लेख किया गया है)।

+0

+1, मैंने इस विधि पर आपके उत्तर में आपके उत्तर के संदर्भ के साथ टिप्पणी की। –

+0

अपमानजनक, लेकिन अपमानजनक। बस प्रत्येक तत्व में एक सूचक सूचक है। यह इतना आसान, कम दर्दनाक है और अच्छी तरह से समझ में आता है और अच्छी तरह से पहचाना जाता है। –

1

नोड्स से उनके पूर्वजों के पॉइंटर्स को थ्रेडेड पेड़ नामक संरचना का उपयोग करके अतिरिक्त भंडारण (अच्छी तरह से, दो बिट्स प्रति नोड) के साथ किया जा सकता है। एक थ्रेडेड पेड़ में, शून्य लिंक को शून्य सूचक के बजाय थोड़ा सा राज्य द्वारा दर्शाया जाता है। फिर, आप पॉइंटर्स के साथ नल लिंक को अन्य नोड्स में प्रतिस्थापित कर सकते हैं: बाएं लिंक उत्तराधिकारी नोड को इनऑर्डर ट्रैवर्सल में इंगित करते हैं, और पूर्ववर्ती के लिए सही लिंक।

 
             ╭─┬────────────────────────────────────────╮ 
    ╭─────────────────────────▶┏━━━┯━━━┯━━▼┓│          │ 
    │      ╭─╂─ │ X │ ─╂╯          │ 
    │      ▼ ┗━━━┷━━━┷━━━┛           │ 
    │     ┏━━━┯━━━┯━━━┓            │ 
    │    ╭────╂─ │ A │ ─╂──╮           │ 
    │    ▼ ┗━━━┷━━━┷━━━┛ │           │  
    │  ┏━━━┯━━━┯━━━┓ ▲   │  ┏━━━┯━━━┯━━━┓      │ 
    │  ╭─╂─ │ B │ ─╂────┤   ├────────╂─ │ C │ ─╂───────╮    │ 
    │  ▼ ┗━━━┷━━━┷━━━┛ │   ▼  ┗━━━┷━━━┷━━━┛  ▼    │ 
    │┏━━━┯━━━┯━━━┓ ▲   │ ┏━━━┯━━━┯━━━┓  ▲   ┏━━━┯━━━┯━━━┓  │ 
    ╰╂─ │ D │ ─╂─╯   ╰───╂ │ E │ ─╂╮  │  ╭╂─ │ F │ ─╂╮  │ 
    ┗━━━┷━━━┷━━━┛    ┗━━━┷━━━┷━━━┛▼  │  ▼┗━━━┷━━━┷━━━┛▼  │ 
            ▲ ┏━━━┯━━━┯━━━┓ │ ┏━━━┯━━━┯━━━┓ ▲ ┏━━━┯━━━┯━━━┓│ 
            ╰─╂─ │ G │ ╂──┴─╂─ │ H │ ─╂─┴─╂─ │ J │ ─╂╯ 
             ┗━━━┷━━━┷━━━┛ ┗━━━┷━━━┷━━━┛ ┗━━━┷━━━┷━━━┛ 

एक बार जब आप संरचना है, एक inorder ट्रावर्सल कर बहुत, बहुत आसान है::

 
Inorder-Successor(p) 
    p points to a node. This routine finds the successor of p in 
    an inorder traversal and returns a pointer to that node 

    qp.right 
    Ifp.rtag = 0 Then 
     Whileq.ltag = 0 Do 
      qq.left 
     End While 
    End If 

    Returnq 

यहाँ एक यूनिकोड-भारी चित्र है (एक्स एक हैडर नोड ट्री को नियंत्रित करने के लिए प्रयोग किया जाता प्रतिनिधित्व करता है) थ्रेडेड पेड़ों पर बहुत अधिक जानकारी में कंप्यूटर प्रोग्रामिंग की कला Ch.2 §3.1 या इंटरनेट के चारों ओर बिखरी हुई है।

+2

और यह ओ (एन) ऑक्स स्टोरेज है;) –

23

गीज़, मुझे वास्तव में इसे Knuth से टाइप करना होगा। यह समाधान जोसेफ एम मॉरिस [इंफ। प्रोक। पत्र (1 9 7 9), 1 9 7-200]। जहां तक ​​मैं कह सकता हूं, यह ओ (एनएलओएनएन) समय में चलता है।

static void VisitInO1Memory (Node root, Action<Node> preorderVisitor) { 
    Node parent = root ; 
    Node right = null ; 
    Node curr ; 
    while (parent != null) { 
    curr = parent.left ; 
    if (curr != null) { 
     // search for thread 
     while (curr != right && curr.right != null) 
     curr = curr.right ; 

     if (curr != right) { 
     // insert thread 
     assert curr.right == null ; 
     curr.right = parent ; 
     preorderVisitor (parent) ; 
     parent = parent.left ; 
     continue ; 
     } else 
     // remove thread, left subtree of P already traversed 
     // this restores the node to original state 
     curr.right = null ; 
    } else 
     preorderVisitor (parent) ; 

    right = parent ; 
    parent = parent.right ; 
    } 
} 

class Node 
{ 
    public Node left ; 
    public Node right ; 
} 
+0

यह पेड़ को नष्ट कर देता है, है ना? –

+5

नहीं, यह अस्थायी रूप से कुछ पत्तियों से अस्थायी रूप से जोड़ता है। – Svante

+0

आह, बहुत अच्छा :) –

-3

क्या ओ (1) सहायक अंतरिक्ष में एक बाइनरी पेड़ पर फिर से शुरू करना संभव है।

struct node { node * father, * right, * left; int value; }; 

यह संरचना आपको बाइनरी पेड़ के माध्यम से किसी भी दिशा में 1-चरण को स्थानांतरित करने में सक्षम हो जाएगी।
लेकिन अभी भी पुनरावृत्ति में आपको पथ रखने की जरूरत है!

1

"datastructures और अपने एल्गोरिदम" हैरी लुईस और लैरी Denenberg द्वारा में अपने माता पिता के नोड सांकेतिक शब्दों में बदलना का वर्णन एक द्विआधारी पेड़ की लगातार अंतरिक्ष ट्रेवर्सल के लिए लिंक उलट ट्रेवर्सल। इसके लिए आपको प्रत्येक नोड पर पैरेंट पॉइंटर की आवश्यकता नहीं है। ट्रैवर्सल पेड़ में मौजूदा पॉइंटर्स का उपयोग बैक ट्रैकिंग के लिए पथ को स्टोर करने के लिए करता है। 2-3 अतिरिक्त नोड संदर्भों की आवश्यकता है। जैसे ही हम नीचे जाते हैं, ट्रैवर्सल दिशा (ऊपर या नीचे) का ट्रैक रखने के लिए प्रत्येक नोड पर थोड़ा सा। पुस्तक से इस एल्गोरिदम के कार्यान्वयन में, प्रोफाइलिंग से पता चलता है कि इस ट्रैवर्सल में बहुत कम स्मृति/प्रोसेसर समय है। जावा में एक कार्यान्वयन here है।

+0

उस बिट सरणी को पकड़ने के लिए आपको अतिरिक्त डेटा संरचना की आवश्यकता है, यह ओ (1) स्पेस नहीं है। – shinzou

संबंधित मुद्दे