11

क्या बीएसटी पर एक पुनरावर्तक इन-ऑर्डर-ट्रैवर्सल करना संभव है, जिसके पास visited ध्वज या stack का उपयोग किए बिना किसी नोड के माता-पिता पॉइंटर (रूट का पैरेंट null) है।रिकर्सन या स्टैक के बिना बीएसटी के इन-ऑर्डर ट्रैवर्सल को कैसे करें लेकिन पैरेंट पॉइंटर्स का उपयोग कैसे करें?

मैं googled और एक जवाब नहीं मिला। मुद्दा यह है कि, मुझे कैसे पता चलेगा - एक निश्चित नोड पर - कि मैं बस इसके पास आया हूं, लेकिन मैंने इसके नीचे सबकुछ खत्म कर लिया है?

+2

रिकर्सन? हालांकि यह ढेर का अप्रत्यक्ष उपयोग है। – Shubham

+1

यह उन मूर्ख साक्षात्कार प्रश्नों में से एक की तरह लगता है। रिकर्सन अपेक्षित उत्तर की संभावना है। – pablochan

+4

[@ शुभम, @ पाब्लोचन] यदि आप फिर से प्रश्न पढ़ते हैं, तो आपको शब्द * पुनरावृत्त * स्पष्ट रूप से लिखा जाएगा। – OmarOthman

उत्तर

13

आप ऐसा कर सकते हैं, आपको वर्तमान नोड के साथ अंतिम बार देखा गया नोड याद रखना होगा। ऐसा करने से यह समस्या बयान से अस्वीकृत नहीं है: प्रत्येक नोड पर दोनों visited ध्वज और stack (सबसे खराब स्थिति) हे ( n) कर रहे हैं, पिछले नोड याद सिर्फ हे है (1)।

सी # में, एल्गोरिथ्म ऐसा दिखाई दे सकता:

static void Walk(Node node) 
{ 
    Node lastNode = null; 
    while (node != null) 
    { 
     if (lastNode == node.Parent) 
     { 
      if (node.Left != null) 
      { 
       lastNode = node; 
       node = node.Left; 
       continue; 
      } 
      else 
       lastNode = null; 
     } 
     if (lastNode == node.Left) 
     { 
      Output(node); 

      if (node.Right != null) 
      { 
       lastNode = node; 
       node = node.Right; 
       continue; 
      } 
      else 
       lastNode = null; 
     } 
     if (lastNode == node.Right) 
     { 
      lastNode = node; 
      node = node.Parent; 
     } 
    } 
} 
+3

यह कोड एक अनंत लूप में है। जब यह बाईं ओर से आने के बाद, एक पत्ते पर जाने की कोशिश करता है, तो अंतिम नोड शून्य हो जाएगा, और जब यह दाएं तरफ घुसने का इरादा रखता है, तो यह (अंतिम == नोड.ए.बी.) शाखा में जाएगा, और एक ही बात फिर से करो। – Wilhelm

+0

@ विल्हेल्म नो, यह नहीं होगा। ध्यान दें कि दाएं तरफ की शाखा 'if' में है, न कि 'और अगर'। तो, यह बाईं तरफ से आने के बाद ('lastNode == नोड। लिफ्ट 'शाखा में), यह तुरंत दाएं तरफ देखता है (' lastNode == node.Right') और उसके बाद ही यह खत्म हो जाता है। – svick

+0

तो आपको एक माता-पिता सूचक की आवश्यकता है, तो क्या यह अन्यथा करना असंभव है? – bneil

-1

कुंजी माता पिता संकेत (या पेड़ उत्परिवर्तित करने की क्षमता) है, लेकिन आप अतिरिक्त राज्य के एक निरंतर राशि की जरूरत है (जैसे, निम्नलिखित coroutine के कार्यक्रम काउंटर)।

  1. रूट पर सेट v।
  2. जबकि वी में एक बायां बच्चा है, तो अपने बाएं बच्चे को सेट करें।
  3. यील्ड बनाम
  4. यदि वी रूट है, तो वापस आएं।
  5. पी को वी के माता-पिता को सेट करें।
  6. यदि पी का सही बच्चा वी है, तो पी को सेट करें और चरण 4 पर जाएं।
  7. यील्ड पी।
  8. पी एक सही बच्चा है, तो पी के सही बच्चे को वी सेट और पी कदम 2.
  9. सेट वी और चरण 4.
+1

आपका कोड बहुत से परीक्षण मामलों में विफल रहता है। मैंने इसे सी ++ में सटीक स्पेगेटी कोड में अनुवादित किया है और इसे मेरे टेस्ट सूट के खिलाफ चलाया है। – OmarOthman

9

यहाँ एक और तरीका यह करने के लिए है जाने के लिए जाना। मुझे लगता है कि यह अनिवार्य रूप से svick के उत्तर के बराबर है, लेकिन अतिरिक्त चर से बचाता है। इस संस्करण में अजगर में कार्यान्वित किया जाता:

node=root 
if node is not None: 
    while node.left is not None: 
    node=node.left 
    while node is not None: 
    output(node) 
    if node.right is not None: 
     node=node.right 
     while node.left is not None: 
     node=node.left 
    else: 
     while node.parent is not None and node.parent.right is node: 
     node=node.parent 
     node=node.parent 

जो भी नोड आप पिछली बार देखे अगले नोड आप यात्रा करने के लिए की जरूरत है कि निर्धारित करता है। यदि आपने अभी नोड एक्स का दौरा किया है, तो आपको एक्स के दाईं ओर बाएं सबसे नोड पर जाना होगा। यदि एक्स का कोई सही बच्चा नहीं है, तो अगला नोड पहला पूर्वज है जहां नोड एक्स दाएं से नहीं आया था पक्ष।

+0

कोड जो वॉन कैटो प्रदान करता है वह वास्तव में पेड़ को क्रम में पार करता है, लेकिन जहां तक ​​मैं कह सकता हूं, यह पेड़ के अंत तक पहुंचने के बाद एक अनंत लूप में चलता है। क्या किसी को इसे ठीक करने के तरीके के बारे में पता है? –

+0

@ नाथन: मुझे अनंत लूप नहीं दिख रहा है जिसके बारे में आप बात कर रहे हैं। जब यह सही-अधिकांश नोड तक जाता है, तो आखिरी पाश इसे रूट पर वापस भेजना चाहिए और अंत में रूट के पैरेंट को नोड सेट करना चाहिए, जो कि कोई नहीं होना चाहिए। बाहरी जबकि लूप तब समाप्त हो जाएगा। –

+0

अच्छा और साफ कार्यान्वयन +1 – Johan

5

svick का सही विचार (उसका answer देखें) का उपयोग करके, यह कोड C++ में परीक्षण किया गया है। ध्यान दें कि मैंने अपने कोड का परीक्षण नहीं किया है या यहां तक ​​कि इसे भी नहीं देखा है, मैंने अभी अपना विचार लिया और अपना खुद का कार्य लागू किया।

void in_order_traversal_iterative_with_parent(node* root) { 
node* current = root; 
node* previous = NULL; 

while (current) { 
    if (previous == current->parent) { // Traversing down the tree. 
     previous = current; 
     if (current->left) { 
      current = current->left; 
     } else { 
      cout << ' ' << current->data; 
      if (current->right) 
       current = current->right; 
      else 
       current = current->parent; 
     } 
    } else if (previous == current->left) { // Traversing up the tree from the left. 
     previous = current; 
     cout << ' ' << current->data; 
     if (current->right) 
      current = current->right; 
     else 
      current = current->parent; 
    } else if (previous == current->right) { // Traversing up the tree from the right. 
     previous = current; 
     current = current->parent; 
    } 
} 

cout << endl; 
} 
-2

यह सी में है ++:

void InOrder(Node *r) 
{ 
    if(r==NULL) 
     return; 

    Node *t=r; 

    while(t!=NULL) 
     t=t->left; 

    while(t!=r) 
    { 
    if(t==(t->parent->left)) 
    { 
     cout<<t->parent->data; 
     t=t->parent->right; 
     if(t!=NULL) 
     { 
     while(t!=NULL) 
      t=t->left; 
     } 
     if(t==NULL) 
      t=t->parent; 
    } 
    if(t==t->parent->right) 
    { 
     t=t->parent; 
    } 
    } 
} 
0
public void inorderNoStack() { 
    if (root == null) { 
     return; 
    } 

    // use the previous to always track the last visited node 
    // helps in deciding if we are going down/up 
    Node prev = null; 

    Node curr = root; 

    while (curr != null) { 
     // going down 
     if (prev == null || prev.left == curr || prev.right == curr) { 
      if (curr.left != null) { 
       prev = curr; 
       curr = curr.left; 
       continue; 
      } else { 

       visitn(curr); 

       if (curr.right != null) { 
        prev = curr; 
        curr = curr.right; 
        continue; 
       } else { 
        // swap states 
        prev = curr; 
        curr = prev.parent; 
       } 
      } 
     } 

     // going up after left traversal 
     if (curr != null && prev == curr.left) { 

      visitn(curr); 

      if (curr.right != null) { 
       prev = curr; 
       curr = curr.right; 
       continue; 
      } else { 
       // swap states 
       prev = curr; 
       curr = prev.parent; 
      } 
     } 

     // going up after right traversal 
     if (curr != null && prev == curr.right) { 
      // swap states 
      prev = curr; 
      curr = prev.parent; 
     } 
    } 
} 
+1

कोई स्पष्टीकरण वाले कोड वाले उत्तर बहुत उपयोगी नहीं हैं। – svick

0

मेरे जावा मौजूदा पेड़ पर किसी भी ध्वज को शुरू करने के बिना समाधान। और कोई माता पिता भी नहीं। यह दृष्टिकोण पेड़ की ऊंचाई तक नोड्स रखेगा। कृपया एक नज़र डालें।

https://github.com/skanagavelu/Algorithams/blob/master/src/tree/InOrderTraversalIterative.java

0

चरण 1: एक समारोह जो रिटर्न बारे में आदेश उत्तराधिकारी

चरण 2: वाम-पंथी नोड के साथ शुरू, इन-आदेश उत्तराधिकारी खोजने के लिए जब तक कोई भी

public class TreeNode { 
     int data; 
     TreeNode left; 
     TreeNode right; 
     TreeNode parent; 
    } 

    public class TreeUtility { 
     public void inorderNoRecursion(TreeNode root) { 
     TreeNode current = leftmostNode(root); 
     while(current != null) { 
      System.out.println(current.data); 
      current = inorderSuccessor(current); 
     } 
     } 

     public TreeNode inorderSuccessor(TreeNode node) { 
     if (node.right!=null) { 
      return leftmostNode(node.right); 
     } 

     TreeNode p = node.parent; 
     TreeNode c = node; 
     while(p!=null && c != p.left) { 
      c = p; 
      p = p.parent; 
     } 
     return p; 
     } 

     private TreeNode leftmostNode(TreeNode node) { 
     while (node.left != null) { 
      node = node.left; 
     } 
     return node; 
     } 
    } 
है