📜  以图形方式打印N元树

📅  最后修改于: 2021-04-29 02:46:22             🧑  作者: Mango

给定一个N元树,任务是以图形方式打印N元树。
树的图形表示形式:树的表示形式,其中根部打印在一行中,子节点以子序列打印在一行中,并带有一定的缩进量。
例子:

Input: 
                  0
                / | \
               /  |  \
              1   2   3
             / \    / | \
            4   5  6  7  8
                      |
                      9 
Output:
0
+--- 1
|    +--- 4
|    +--- 5
+--- 2
+--- 3
    +--- 6
    +--- 7
    |    +--- 9
    +--- 8

方法:想法是使用DFS遍历遍历N元树以遍历节点并探索其子节点,直到访问所有节点,然后类似地遍历同级节点。
下面介绍了上述方法的分步算法–

  • 初始化一个变量以存储节点的当前深度,对于根节点,深度为0。
  • 声明一个布尔数组以存储当前的探索深度,并最初将所有深度标记为False。
  • 如果当前节点是根节点,该根节点的深度为0,则只需打印该节点的数据即可。
  • 否则,循环遍历从1到当前节点深度并打印’|’对于每个探查深度,三个空格,对于非探查深度,仅打印三个空格。
  • 打印节点的当前值,然后将输出指针移到下一行。
  • 如果当前节点是该深度的最后一个节点,则将该深度标记为非探测。
  • 同样,使用递归调用探索所有子节点。

下面是上述方法的实现:

C++
// C++ implementation to print
// N-ary Tree graphically
 
#include 
#include 
#include 
 
using namespace std;
 
// Structure of the node
struct tnode {
    int n;
    list root;
    tnode(int data)
        : n(data)
    {
    }
};
 
// Function to print the
// N-ary tree graphically
void printNTree(tnode* x,
    vector flag,
    int depth = 0, bool isLast = false)
{
    // Condition when node is None
    if (x == NULL)
        return;
     
    // Loop to print the depths of the
    // current node
    for (int i = 1; i < depth; ++i) {
         
        // Condition when the depth
        // is exploring
        if (flag[i] == true) {
            cout << "| "
                << " "
                << " "
                << " ";
        }
         
        // Otherwise print
        // the blank spaces
        else {
            cout << " "
                << " "
                << " "
                << " ";
        }
    }
     
    // Condition when the current
    // node is the root node
    if (depth == 0)
        cout << x->n << '\n';
     
    // Condtion when the node is
    // the last node of
    // the exploring depth
    else if (isLast) {
        cout << "+--- " << x->n << '\n';
         
        // No more childrens turn it
        // to the non-exploring depth
        flag[depth] = false;
    }
    else {
        cout << "+--- " << x->n << '\n';
    }
 
    int it = 0;
    for (auto i = x->root.begin();
    i != x->root.end(); ++i, ++it)
 
        // Recursive call for the
        // children nodes
        printNTree(*i, flag, depth + 1,
            it == (x->root.size()) - 1);
    flag[depth] = true;
}
 
// Function to form the Tree and
// print it graphically
void formAndPrintTree(){
    int nv = 10;
    tnode r(0), n1(1), n2(2),
        n3(3), n4(4), n5(5),
    n6(6), n7(7), n8(8), n9(9);
     
    // Array to keep track
    // of exploring depths
    vector flag(nv, true);
     
    // Tree Formation
    r.root.push_back(&n1);
    n1.root.push_back(&n4);
    n1.root.push_back(&n5);
    r.root.push_back(&n2);
    r.root.push_back(&n3);
    n3.root.push_back(&n6);
    n3.root.push_back(&n7);
    n7.root.push_back(&n9);
    n3.root.push_back(&n8);
 
    printNTree(&r, flag);
}
 
// Driver Code
int main(int argc, char const* argv[])
{
     
    // Function Call
    formAndPrintTree();
    return 0;
}


Java
// Java implementation to print
// N-ary Tree graphically
 
import java.util.*;
 
class GFG{
 
// Structure of the node
static class tnode {
    int n;
    Vector root = new Vector<>();
    tnode(int data)
    {
        this.n = data;
    }
};
 
// Function to print the
// N-ary tree graphically
static void printNTree(tnode x,
    boolean[] flag,
    int depth, boolean isLast )
{
    // Condition when node is None
    if (x == null)
        return;
     
    // Loop to print the depths of the
    // current node
    for (int i = 1; i < depth; ++i) {
         
        // Condition when the depth
        // is exploring
        if (flag[i] == true) {
            System.out.print("| "
               + " "
               + " "
               + " ");
        }
         
        // Otherwise print
        // the blank spaces
        else {
            System.out.print(" "
               + " "
               + " "
               + " ");
        }
    }
     
    // Condition when the current
    // node is the root node
    if (depth == 0)
        System.out.println(x.n);
     
    // Condtion when the node is
    // the last node of
    // the exploring depth
    else if (isLast) {
        System.out.print("+--- " +  x.n + '\n');
         
        // No more childrens turn it
        // to the non-exploring depth
        flag[depth] = false;
    }
    else {
        System.out.print("+--- " +  x.n + '\n');
    }
 
    int it = 0;
    for (tnode i : x.root) {
         ++it;
       
        // Recursive call for the
        // children nodes
        printNTree(i, flag, depth + 1,
            it == (x.root.size()) - 1);
    }
    flag[depth] = true;
}
 
// Function to form the Tree and
// print it graphically
static void formAndPrintTree(){
    int nv = 10;
    tnode r = new tnode(0);
    tnode n1 = new tnode(1);
    tnode n2 = new tnode(2);
    tnode n3 = new tnode(3);
    tnode n4 = new tnode(4);
    tnode n5 = new tnode(5);
    tnode n6 = new tnode(6);
    tnode n7 = new tnode(7);
    tnode n8 = new tnode(8);
    tnode n9 = new tnode(9);
     
    // Array to keep track
    // of exploring depths
    
    boolean[] flag = new boolean[nv];
    Arrays.fill(flag, true);
     
    // Tree Formation
    r.root.add(n1);
    n1.root.add(n4);
    n1.root.add(n5);
    r.root.add(n2);
    r.root.add(n3);
    n3.root.add(n6);
    n3.root.add(n7);
    n7.root.add(n9);
    n3.root.add(n8);
 
    printNTree(r, flag, 0, false);
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Function Call
    formAndPrintTree();
}
}
 
// This code is contributed by gauravrajput1


C#
// C# implementation to print
// N-ary Tree graphically
using System;
using System.Collections.Generic;
 
class GFG
{
 
// Structure of the node
public class tnode
{
   public
 
  int n;
    public
 
 List root = new List();
   public
 
  tnode(int data)
  {
     this.n = data;
  }
};
 
// Function to print the
// N-ary tree graphically
static void printNTree(tnode x,
                       bool[] flag,
                       int depth, bool isLast )
{
   
    // Condition when node is None
    if (x == null)
        return;
     
    // Loop to print the depths of the
    // current node
    for (int i = 1; i < depth; ++i)
    {
         
        // Condition when the depth
        // is exploring
        if (flag[i] == true)
        {
            Console.Write("| "
               + " "
               + " "
               + " ");
        }
         
        // Otherwise print
        // the blank spaces
        else
        {
            Console.Write(" "
               + " "
               + " "
               + " ");
        }
    }
     
    // Condition when the current
    // node is the root node
    if (depth == 0)
        Console.WriteLine(x.n);
     
    // Condtion when the node is
    // the last node of
    // the exploring depth
    else if (isLast)
    {
        Console.Write("+--- " +  x.n + '\n');
         
        // No more childrens turn it
        // to the non-exploring depth
        flag[depth] = false;
    }
    else
    {
        Console.Write("+--- " +  x.n + '\n');
    }
 
    int it = 0;
    foreach (tnode i in x.root)
    {
         ++it;
       
        // Recursive call for the
        // children nodes
        printNTree(i, flag, depth + 1,
            it == (x.root.Count) - 1);
    }
    flag[depth] = true;
}
 
// Function to form the Tree and
// print it graphically
static void formAndPrintTree()
{
    int nv = 10;
    tnode r = new tnode(0);
    tnode n1 = new tnode(1);
    tnode n2 = new tnode(2);
    tnode n3 = new tnode(3);
    tnode n4 = new tnode(4);
    tnode n5 = new tnode(5);
    tnode n6 = new tnode(6);
    tnode n7 = new tnode(7);
    tnode n8 = new tnode(8);
    tnode n9 = new tnode(9);
     
    // Array to keep track
    // of exploring depths  
    bool[] flag = new bool[nv];
    for(int i = 0; i < nv; i++)
        flag[i] = true;
     
    // Tree Formation
    r.root.Add(n1);
    n1.root.Add(n4);
    n1.root.Add(n5);
    r.root.Add(n2);
    r.root.Add(n3);
    n3.root.Add(n6);
    n3.root.Add(n7);
    n7.root.Add(n9);
    n3.root.Add(n8);
 
    printNTree(r, flag, 0, false);
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Function Call
    formAndPrintTree();
}
}
 
// This code is contributed by aashish1995


输出
0
+--- 1
|    +--- 4
|    +--- 5
+--- 2
+--- 3
    +--- 6
    +--- 7
    |    +--- 9
    +--- 8

性能分析:

  • 时间复杂度:在上述方法中,有很多研究需要探索耗费O(V)时间的所有顶点。因此,此方法的时间复杂度将为O(V)
  • 辅助空间的复杂性:在上述方法中,存在用于存储探索深度的额外空间。因此,上述方法的辅助空间复杂度将为O(V)