📌  相关文章
📜  迭代前序遍历

📅  最后修改于: 2022-05-13 01:57:17.234000             🧑  作者: Mango

迭代前序遍历

给定一棵二叉树,编写一个迭代函数来打印给定二叉树的前序遍历。
有关二叉树的递归前序遍历,请参阅this。要将固有的递归过程转换为迭代,我们需要一个显式堆栈。以下是一个简单的基于堆栈的迭代过程来打印 Preorder traversal。
1)创建一个空栈nodeStack ,并将根节点压入栈。
2)nodeStack不为空时执行以下操作。
…… a)从堆栈中弹出一个项目并打印它。
…… b)将弹出项目的右孩子推入堆栈
…… c)将弹出项目的左孩子推入堆栈
右孩子被推到左孩子之前,以确保首先处理左子树。

C++


Java
// Java program to implement iterative preorder traversal
import java.util.Stack;
 
// A binary tree node
class Node {
 
    int data;
    Node left, right;
 
    Node(int item)
    {
        data = item;
        left = right = null;
    }
}
 
class BinaryTree {
 
    Node root;
 
    void iterativePreorder()
    {
        iterativePreorder(root);
    }
 
    // An iterative process to print preorder traversal of Binary tree
    void iterativePreorder(Node node)
    {
 
        // Base Case
        if (node == null) {
            return;
        }
 
        // Create an empty stack and push root to it
        Stack nodeStack = new Stack();
        nodeStack.push(root);
 
        /* Pop all items one by one. Do following for every popped item
         a) print it
         b) push its right child
         c) push its left child
         Note that right child is pushed first so that left is processed first */
        while (nodeStack.empty() == false) {
 
            // Pop the top item from stack and print it
            Node mynode = nodeStack.peek();
            System.out.print(mynode.data + " ");
            nodeStack.pop();
 
            // Push right and left children of the popped node to stack
            if (mynode.right != null) {
                nodeStack.push(mynode.right);
            }
            if (mynode.left != null) {
                nodeStack.push(mynode.left);
            }
        }
    }
 
    // driver program to test above functions
    public static void main(String args[])
    {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(10);
        tree.root.left = new Node(8);
        tree.root.right = new Node(2);
        tree.root.left.left = new Node(3);
        tree.root.left.right = new Node(5);
        tree.root.right.left = new Node(2);
        tree.iterativePreorder();
    }
}
 
// This code has been contributed by Mayank Jaiswal


Python3
# Python program to perform iterative preorder traversal
 
# A binary tree node
class Node:
 
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# An iterative process to print preorder traversal of BT
def iterativePreorder(root):
     
    # Base CAse
    if root is None:
        return
 
    # create an empty stack and push root to it
    nodeStack = []
    nodeStack.append(root)
 
    # Pop all items one by one. Do following for every popped item
    # a) print it
    # b) push its right child
    # c) push its left child
    # Note that right child is pushed first so that left
    # is processed first */
    while(len(nodeStack) > 0):
         
        # Pop the top item from stack and print it
        node = nodeStack.pop()
        print (node.data, end=" ")
         
        # Push right and left children of the popped node
        # to stack
        if node.right is not None:
            nodeStack.append(node.right)
        if node.left is not None:
            nodeStack.append(node.left)
     
# Driver program to test above function
root = Node(10)
root.left = Node(8)
root.right = Node(2)
root.left.left = Node(3)
root.left.right = Node(5)
root.right.left = Node(2)
iterativePreorder(root)
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)


C#
// C# program to implement iterative
// preorder traversal
using System;
using System.Collections.Generic;
 
// A binary tree node
public class Node {
    public int data;
    public Node left, right;
 
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
 
class GFG {
    public Node root;
 
    public virtual void iterativePreorder()
    {
        iterativePreorder(root);
    }
 
    // An iterative process to print preorder
    // traversal of Binary tree
    public virtual void iterativePreorder(Node node)
    {
 
        // Base Case
        if (node == null) {
            return;
        }
 
        // Create an empty stack and push root to it
        Stack nodeStack = new Stack();
        nodeStack.Push(root);
 
        /* Pop all items one by one. Do following
       for every popped item
    a) print it
    b) push its right child
    c) push its left child
    Note that right child is pushed first so
    that left is processed first */
        while (nodeStack.Count > 0) {
 
            // Pop the top item from stack and print it
            Node mynode = nodeStack.Peek();
            Console.Write(mynode.data + " ");
            nodeStack.Pop();
 
            // Push right and left children of
            // the popped node to stack
            if (mynode.right != null) {
                nodeStack.Push(mynode.right);
            }
            if (mynode.left != null) {
                nodeStack.Push(mynode.left);
            }
        }
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        GFG tree = new GFG();
        tree.root = new Node(10);
        tree.root.left = new Node(8);
        tree.root.right = new Node(2);
        tree.root.left.left = new Node(3);
        tree.root.left.right = new Node(5);
        tree.root.right.left = new Node(2);
        tree.iterativePreorder();
    }
}
 
// This code is contributed by Shrikant13


Javascript


C++
#include 
using namespace std;
 
// Tree Node
struct Node {
    int data;
    Node *left, *right;
 
    Node(int data)
    {
        this->data = data;
        this->left = this->right = NULL;
    }
};
 
// Iterative function to do Preorder traversal of the tree
void preorderIterative(Node* root)
{
    if (root == NULL)
        return;
 
    stack st;
 
    // start from root node (set current node to root node)
    Node* curr = root;
 
    // run till stack is not empty or current is
    // not NULL
    while (!st.empty() || curr != NULL) {
        // Print left children while exist
        // and keep pushing right into the
        // stack.
        while (curr != NULL) {
            cout << curr->data << " ";
 
            if (curr->right)
                st.push(curr->right);
 
            curr = curr->left;
        }
 
        // We reach when curr is NULL, so We
        // take out a right child from stack
        if (st.empty() == false) {
            curr = st.top();
            st.pop();
        }
    }
}
 
// Driver Code
int main()
{
    Node* root = new Node(10);
    root->left = new Node(20);
    root->right = new Node(30);
    root->left->left = new Node(40);
    root->left->left->left = new Node(70);
    root->left->right = new Node(50);
    root->right->left = new Node(60);
    root->left->left->right = new Node(80);
 
    preorderIterative(root);
 
    return 0;
}


Java
import java.util.Stack;
 
// A binary tree node
class Node
{
    int data;
    Node left, right;
 
    Node(int item)
    {
        data = item;
        left = right = null;
    }
}
 
class BinaryTree{
 
Node root;
 
void preorderIterative()
{
    preorderIterative(root);
}
 
// Iterative function to do Preorder
// traversal of the tree
void preorderIterative(Node node)
{
    if (node == null)
    {
        return;
    }
 
    Stack st = new Stack();
     
    // Start from root node (set curr
    // node to root node)
    Node curr = node;
     
    // Run till stack is not empty or
    // current is not NULL
    while (curr != null || !st.isEmpty())
    {
         
        // Print left children while exist
        // and keep pushing right into the 
        // stack.
        while (curr != null)
        {
            System.out.print(curr.data + " ");
             
            if (curr.right != null)
                st.push(curr.right);
                 
            curr = curr.left;
        }
         
        // We reach when curr is NULL, so We
        // take out a right child from stack
        if (!st.isEmpty())
        {
            curr = st.pop();
        }
    }
}
 
// Driver code
public static void main(String args[])
{
    BinaryTree tree = new BinaryTree();
     
    tree.root = new Node(10);
    tree.root.left = new Node(20);
    tree.root.right = new Node(30);
    tree.root.left.left = new Node(40);
    tree.root.left.left.left = new Node(70);
    tree.root.left.right = new Node(50);
    tree.root.right.left = new Node(60);
    tree.root.left.left.right = new Node(80);
     
    tree.preorderIterative();
}
}
 
// This code is contributed by Vivek Singh Bhadauria


Python3
# Tree Node
class Node:
 
    def __init__(self, data = 0):
        self.data = data
        self.left = None
        self.right = None
     
# Iterative function to do Preorder traversal of the tree
def preorderIterative(root):
 
    if (root == None):
        return
 
    st = []
 
    # start from root node (set current node to root node)
    curr = root
 
    # run till stack is not empty or current is
    # not NULL
    while (len(st) or curr != None):
     
        # Print left children while exist
        # and keep appending right into the
        # stack.
        while (curr != None):
         
            print(curr.data, end = " ")
 
            if (curr.right != None):
                st.append(curr.right)
 
            curr = curr.left
         
        # We reach when curr is NULL, so We
        # take out a right child from stack
        if (len(st) > 0):
            curr = st[-1]
            st.pop()
             
# Driver Code
 
root = Node(10)
root.left = Node(20)
root.right = Node(30)
root.left.left = Node(40)
root.left.left.left = Node(70)
root.left.right = Node(50)
root.right.left = Node(60)
root.left.left.right = Node(80)
 
preorderIterative(root)
 
# This code is contributed by Arnab Kundu


C#


Javascript


输出:
10 8 3 5 2 2

时间复杂度:O(N)
辅助空间:O(N),其中 N 是树中节点的总数。

空间优化解决方案:想法是从根节点开始遍历树,并在存在时继续打印左孩子,同时将每个节点的右孩子压入辅助堆栈。一旦我们到达一个空节点,从辅助堆栈中弹出一个右子节点,并在辅助堆栈不为空时重复该过程。

下面是上述方法的实现:

C++

#include 
using namespace std;
 
// Tree Node
struct Node {
    int data;
    Node *left, *right;
 
    Node(int data)
    {
        this->data = data;
        this->left = this->right = NULL;
    }
};
 
// Iterative function to do Preorder traversal of the tree
void preorderIterative(Node* root)
{
    if (root == NULL)
        return;
 
    stack st;
 
    // start from root node (set current node to root node)
    Node* curr = root;
 
    // run till stack is not empty or current is
    // not NULL
    while (!st.empty() || curr != NULL) {
        // Print left children while exist
        // and keep pushing right into the
        // stack.
        while (curr != NULL) {
            cout << curr->data << " ";
 
            if (curr->right)
                st.push(curr->right);
 
            curr = curr->left;
        }
 
        // We reach when curr is NULL, so We
        // take out a right child from stack
        if (st.empty() == false) {
            curr = st.top();
            st.pop();
        }
    }
}
 
// Driver Code
int main()
{
    Node* root = new Node(10);
    root->left = new Node(20);
    root->right = new Node(30);
    root->left->left = new Node(40);
    root->left->left->left = new Node(70);
    root->left->right = new Node(50);
    root->right->left = new Node(60);
    root->left->left->right = new Node(80);
 
    preorderIterative(root);
 
    return 0;
}

Java

import java.util.Stack;
 
// A binary tree node
class Node
{
    int data;
    Node left, right;
 
    Node(int item)
    {
        data = item;
        left = right = null;
    }
}
 
class BinaryTree{
 
Node root;
 
void preorderIterative()
{
    preorderIterative(root);
}
 
// Iterative function to do Preorder
// traversal of the tree
void preorderIterative(Node node)
{
    if (node == null)
    {
        return;
    }
 
    Stack st = new Stack();
     
    // Start from root node (set curr
    // node to root node)
    Node curr = node;
     
    // Run till stack is not empty or
    // current is not NULL
    while (curr != null || !st.isEmpty())
    {
         
        // Print left children while exist
        // and keep pushing right into the 
        // stack.
        while (curr != null)
        {
            System.out.print(curr.data + " ");
             
            if (curr.right != null)
                st.push(curr.right);
                 
            curr = curr.left;
        }
         
        // We reach when curr is NULL, so We
        // take out a right child from stack
        if (!st.isEmpty())
        {
            curr = st.pop();
        }
    }
}
 
// Driver code
public static void main(String args[])
{
    BinaryTree tree = new BinaryTree();
     
    tree.root = new Node(10);
    tree.root.left = new Node(20);
    tree.root.right = new Node(30);
    tree.root.left.left = new Node(40);
    tree.root.left.left.left = new Node(70);
    tree.root.left.right = new Node(50);
    tree.root.right.left = new Node(60);
    tree.root.left.left.right = new Node(80);
     
    tree.preorderIterative();
}
}
 
// This code is contributed by Vivek Singh Bhadauria

Python3

# Tree Node
class Node:
 
    def __init__(self, data = 0):
        self.data = data
        self.left = None
        self.right = None
     
# Iterative function to do Preorder traversal of the tree
def preorderIterative(root):
 
    if (root == None):
        return
 
    st = []
 
    # start from root node (set current node to root node)
    curr = root
 
    # run till stack is not empty or current is
    # not NULL
    while (len(st) or curr != None):
     
        # Print left children while exist
        # and keep appending right into the
        # stack.
        while (curr != None):
         
            print(curr.data, end = " ")
 
            if (curr.right != None):
                st.append(curr.right)
 
            curr = curr.left
         
        # We reach when curr is NULL, so We
        # take out a right child from stack
        if (len(st) > 0):
            curr = st[-1]
            st.pop()
             
# Driver Code
 
root = Node(10)
root.left = Node(20)
root.right = Node(30)
root.left.left = Node(40)
root.left.left.left = Node(70)
root.left.right = Node(50)
root.right.left = Node(60)
root.left.left.right = Node(80)
 
preorderIterative(root)
 
# This code is contributed by Arnab Kundu

C#

Javascript


输出:
10 20 40 70 80 50 30 60

时间复杂度:O(N)
辅助空间:O(H),其中 H 是树的高度。