📜  N元树的迭代预遍历

📅  最后修改于: 2021-04-17 12:39:16             🧑  作者: Mango

给定一个Kary树。任务是编写一个迭代程序来执行给定n元树的预遍历。

例子:

Input: 3-Array Tree  
                   1
                 / | \
                /  |   \
              2    3     4
             / \       / | \
            5    6    7  8  9
           /   / | \ 
          10  11 12 13

Output: 1 2 5 10 6 11 12 13 3 4 7 8 9

Input:  3-Array Tree
                   1
                 / | \
                /  |   \
              2    3     4
             / \       / | \
            5    6    7  8  9

Output: 1 2 5 6 3 4 7 8 9

N元树的预遍历类似于二叉搜索树或二叉树的预遍历,唯一的区别是,父级的所有子节点都按从左到右的顺序遍历。
二叉树的迭代预遍历。

遍历期间要处理的案例:此迭代预遍历算法已处理了两种情况:

  1. 如果堆栈顶部是叶节点,则将其从堆栈中删除
  2. 如果“堆栈顶部”是“有孩子的父母”:
    • 一旦找到一个未访问的孩子(从左到右的顺序),将其推入堆栈并将其存储在
      辅助列出并标记下一个访问的孩子,然后再次从案例1开始探索这个新访问的孩子。
    • 如果已访问了父节点从左到右的所有子节点,请从中删除父节点。
      堆栈。

注意:在下面的Python实现中,由于其高效的附加和弹出操作,因此使用“出队”来实现堆栈而不是列表。

下面是上述方法的实现:

C++
// C++ program for Iterative Preorder
// Traversal of N-ary Tree.
// Preorder{ Root, print children
// from left to right.
#include 
using namespace std;
 
// Node Structure of K-ary Tree
class NewNode
{
    public:
     
        int key;
         
        // All children are stored in a list
        vector child;
        NewNode(int val) : key(val) {}
};
 
// Utility function to print the
// preorder of the given K-Ary Tree
void preorderTraversal(NewNode *root)
{
    stack Stack;
     
    // 'Preorder'-> contains all the
    // visited nodes
    vector Preorder;
     
    Preorder.push_back(root->key);
    Stack.push(root);
     
    while (!Stack.empty())
    {
         
        // 'Flag' checks whether all the child
        // nodes have been visited.
        int flag = 0;
         
        // CASE 1- If Top of the stack is a leaf
        // node then remove it from the stack{
        if (Stack.top()->child.size() == 0)
        {
            Stack.pop();
        }
         
        // CASE 2- If Top of the stack is
        // Parent with children{
        else
        {
            NewNode *Par = Stack.top();
             
            // a)As soon as an unvisited child is
            // found(left to right sequence),
            // Push it to Stack and Store it in
            // Auxillary List(Marked Visited)
            // Start Again from Case-1, to explore
            // this newly visited child
            for(int i = 0; i < Par->child.size(); i++)
            {
                if (find(Preorder.begin(), Preorder.end(),
                    Par->child[i]->key) == Preorder.end())
                {
                    flag = 1;
                    Stack.push(Par->child[i]);
                    Preorder.push_back(Par->child[i]->key);
                    break;
                }
            }
             
            // b)If all Child nodes from left to right
            // of a Parent have been visited
            // then remove the parent from the stack.
            if (flag == 0)
            {
                Stack.pop();
            }
        }
    }
    for(auto i : Preorder)
    {
        cout << i << " ";
    }
    cout << endl;
}
 
// Driver Code
int main()
{
     
    // input nodes
    /*
             1
          /  |  \
         /   |   \
        2    3    4
       / \      / | \
      /   \    7  8  9
     5     6
    /    / | \
   10   11 12 13
    */
     
    NewNode *root = new NewNode(1);
    root->child.push_back(new NewNode(2));
    root->child.push_back(new NewNode(3));
    root->child.push_back(new NewNode(4));
     
    root->child[0]->child.push_back(new NewNode(5));
    root->child[0]->child[0]->child.push_back(new NewNode(10));
    root->child[0]->child.push_back(new NewNode(6));
    root->child[0]->child[1]->child.push_back(new NewNode(11));
    root->child[0]->child[1]->child.push_back(new NewNode(12));
    root->child[0]->child[1]->child.push_back(new NewNode(13));
    root->child[2]->child.push_back(new NewNode(7));
    root->child[2]->child.push_back(new NewNode(8));
    root->child[2]->child.push_back(new NewNode(9));
     
    preorderTraversal(root);
}
 
// This code is contributed by sanjeev2552


Python3
# Python3 program for Iterative Preorder
# Traversal of N-ary Tree.
# Preorder: Root, print children
# from left to right.
 
from collections import deque
 
# Node Structure of K-ary Tree
class NewNode():
 
    def __init__(self, val):
        self.key = val
        # all children are stored in a list
        self.child =[]
 
 
# Utility function to print the
# preorder of the given K-Ary Tree
def preorderTraversal(root):
 
    Stack = deque([])
    # 'Preorder'-> contains all the
    # visited nodes.
    Preorder =[]
    Preorder.append(root.key)
    Stack.append(root)
    while len(Stack)>0:
        # 'Flag' checks whether all the child
        # nodes have been visited.
        flag = 0
        # CASE 1- If Top of the stack is a leaf
        # node then remove it from the stack:
        if len((Stack[len(Stack)-1]).child)== 0:
            X = Stack.pop()
            # CASE 2- If Top of the stack is
            # Parent with children:
        else:
            Par = Stack[len(Stack)-1]
        # a)As soon as an unvisited child is
        # found(left to right sequence),
        # Push it to Stack and Store it in
        # Auxillary List(Marked Visited)
        # Start Again from Case-1, to explore
        # this newly visited child
        for i in range(0, len(Par.child)):
            if Par.child[i].key not in Preorder:
                flag = 1
                Stack.append(Par.child[i])
                Preorder.append(Par.child[i].key)
                break;
                # b)If all Child nodes from left to right
                # of a Parent have been visited
                # then remove the parent from the stack.
        if flag == 0:
            Stack.pop()
    print(Preorder)
 
# Execution Start From here
if __name__=='__main__':
# input nodes
                '''
                 
                  1
               /  |  \
              /   |   \
             2    3    4
            / \      / | \
           /   \    7  8  9
          5     6   
         /    / | \
        10   11 12 13
         
                '''
                 
root = NewNode(1)
root.child.append(NewNode(2))
root.child.append(NewNode(3))
root.child.append(NewNode(4))
root.child[0].child.append(NewNode(5))
root.child[0].child[0].child.append(NewNode(10))
root.child[0].child.append(NewNode(6))
root.child[0].child[1].child.append(NewNode(11))
root.child[0].child[1].child.append(NewNode(12))
root.child[0].child[1].child.append(NewNode(13))
root.child[2].child.append(NewNode(7))
root.child[2].child.append(NewNode(8))
root.child[2].child.append(NewNode(9))
     
preorderTraversal(root)


输出:
[1, 2, 5, 10, 6, 11, 12, 13, 3, 4, 7, 8, 9]