Help me understand Inorder Traversal without using recursion

后端 未结 14 2650
别跟我提以往
别跟我提以往 2020-12-12 11:44

I am able to understand preorder traversal without using recursion, but I\'m having a hard time with inorder traversal. I just don\'t seem to get it, perhaps, because I have

相关标签:
14条回答
  • 2020-12-12 12:37

    Simple iterative inorder traversal without recursion

    '''iterative inorder traversal, O(n) time & O(n) space '''
    
    class Node:
        def __init__(self, value, left = None, right = None):
            self.value = value
            self.left = left
            self.right = right
    
    def inorder_iter(root):
    
        stack = [root]
        current = root
    
        while len(stack) > 0:
            if current:
                while current.left:
                    stack.append(current.left)
                    current = current.left
            popped_node = stack.pop()
            current = None
            if popped_node:
                print popped_node.value
                current = popped_node.right
                stack.append(current)
    
    a = Node('a')
    b = Node('b')
    c = Node('c')
    d = Node('d')
    
    b.right = d
    a.left = b
    a.right = c
    
    inorder_iter(a)
    
    0 讨论(0)
  • 2020-12-12 12:40
    def traverseInorder(node):
       lifo = Lifo()
    
      while node is not None:
        if node.left is not None:
           lifo.push(node)
           node = node.left
           continue
    
       print node.value
    
       if node.right is not None:
          node = node.right
          continue
    
       node = lifo.Pop()
       if node is not None :
          print node.value
          node = node.right
    

    PS: I don't know Python so there may be a few syntax issues.

    0 讨论(0)
  • 2020-12-12 12:43

    State can be remembered implicitly,

    traverse(node) {
       if(!node) return;
       push(stack, node);
       while (!empty(stack)) {
         /*Remember the left nodes in stack*/
         while (node->left) {
            push(stack, node->left);
            node = node->left;
          }
    
          /*Process the node*/
          printf("%d", node->data);
    
          /*Do the tail recursion*/
          if(node->right) {
             node = node->right
          } else {
             node = pop(stack); /*New Node will be from previous*/
          }
        }
     }
    
    0 讨论(0)
  • 2020-12-12 12:44

    Here is a sample of in order traversal using stack in c# (.net):

    (for post order iterative you may refer to: Post order traversal of binary tree without recursion)

    public string InOrderIterative()
            {
                List<int> nodes = new List<int>();
                if (null != this._root)
                {
                    Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();
                    var iterativeNode = this._root;
                    while(iterativeNode != null)
                    {
                        stack.Push(iterativeNode);
                        iterativeNode = iterativeNode.Left;
                    }
                    while(stack.Count > 0)
                    {
                        iterativeNode = stack.Pop();
                        nodes.Add(iterativeNode.Element);
                        if(iterativeNode.Right != null)
                        {
                            stack.Push(iterativeNode.Right);
                            iterativeNode = iterativeNode.Right.Left;
                            while(iterativeNode != null)
                            {
                                stack.Push(iterativeNode);
                                iterativeNode = iterativeNode.Left;
                            }
                        }
                    }
                }
                return this.ListToString(nodes);
            }
    

    Here is a sample with visited flag:

    public string InorderIterative_VisitedFlag()
            {
                List<int> nodes = new List<int>();
                if (null != this._root)
                {
                    Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();
                    BinaryTreeNode iterativeNode = null;
                    stack.Push(this._root);
                    while(stack.Count > 0)
                    {
                        iterativeNode = stack.Pop();
                        if(iterativeNode.visted)
                        {
                            iterativeNode.visted = false;
                            nodes.Add(iterativeNode.Element);
                        }
                        else
                        {
                            iterativeNode.visted = true;
                            if(iterativeNode.Right != null)
                            {
                                stack.Push(iterativeNode.Right);
                            }
                            stack.Push(iterativeNode);
                            if (iterativeNode.Left != null)
                            {
                                stack.Push(iterativeNode.Left);
                            }
                        }
                    }
                }
                return this.ListToString(nodes);
            }
    

    the definitions of the binarytreenode, listtostring utility:

    string ListToString(List<int> list)
            {
                string s = string.Join(", ", list);
                return s;
            }
    
    
    class BinaryTreeNode
        {
            public int Element;
            public BinaryTreeNode Left;
            public BinaryTreeNode Right;        
        }
    
    0 讨论(0)
  • 2020-12-12 12:46

    Here is a simple in-order non-recursive c++ code ..

    void inorder (node *n)
    {
        stack s;
    
        while(n){
            s.push(n);
            n=n->left;
        }
    
        while(!s.empty()){
            node *t=s.pop();
            cout<<t->data;
            t=t->right;
    
            while(t){
                s.push(t);
                t = t->left;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-12 12:46

    @Victor, I have some suggestion on your implementation trying to push the state into the stack. I don't see it is necessary. Because every element you take from the stack is already left traversed. so instead of store the information into the stack, all we need is a flag to indicate if the next node to be processed is from that stack or not. Following is my implementation which works fine:

    def intraverse(node):
        stack = []
        leftChecked = False
        while node != None:
            if not leftChecked and node.left != None:
                stack.append(node)
                node = node.left
            else:
                print node.data
                if node.right != None:
                    node = node.right
                    leftChecked = False
                elif len(stack)>0:
                    node = stack.pop()
                    leftChecked = True
                else:
                    node = None
    
    0 讨论(0)
提交回复
热议问题