简体   繁体   English

使用用户在python中创建n元树

[英]Create an n-ary tree in python with user giving edges

I want to create a tree with user giving edges (in format uv) and values. 我想用用户提供边缘(格式为uv)和值来创建树。 The nodes can have any number of children. 节点可以具有任意数量的子代。 For example if given values of 3 nodes are 2 3 4 and edges are given as 1-2 and 2-3 then the tree will be 2 3 4 Also it is not necessary that u < v.And the edge is undirected so i've to find which one occurs close to the root. 例如,如果给定的3个节点的值为2 3 4且边的值为1-2和2-3,则树将为2 3 4也不是u <v。并且边是无向的,所以i' ve查找哪一个发生在根附近。

I've tried a code but it fails for the making a tree like the following but a node can have any number of children 我已经尝试过代码,但是无法制作如下树,但一个节点可以有任意数量的子代

2
 3
  4
   5

Following is the code 以下是代码

class Node : 

# Utility function to create a new tree node 
def __init__(self ,key): 
    self.key = key 
    self.child = []



# Prints the n-ary tree level wise 
def printNodeLevelWise(root): 
if root is None: 
    return

# create a queue and enqueue root to it 
queue = [] 
queue.append(root) 

# Do level order traversal. Two loops are used 
# to make sure that different levels are printed 
# in different lines 
while(len(queue) >0): 

    n = len(queue) 
    while(n > 0) : 

        # Dequeue an item from queue and print it 
        p = queue[0] 
        queue.pop(0) 
        print p.key, 

        # Enqueue all children of the dequeued item 
        for index, value in enumerate(p.child): 
            queue.append(value) 

        n -= 1
    print "" # Seperator between levels 


# test case
t = raw_input()
t=int(t)
while(t > 0):
# number of nodes
n = raw_input()
n=int(n)
# array to keep node value
a = []
nums = raw_input().split()
for i in nums: a.append(int(i))
n = n -1
root = Node(a[0])
i = 1
for j in range(0, n):
    u, v = raw_input().split()
    u=int(u)
    v=int(v)
    if(u == 1):
        root.child.append(Node(a[i]))
    else:
        root.child[u-2].child.append(Node(a[i]))
    i=i+1
t=t-1
printNodeLevelWise(root)

I know the correction should be done at root.child[u-2].child.append(Node(a[i])) I expect the output to be 我知道更正应该在root.child[u-2].child.append(Node(a[i]))我希望输出是

2
 3
  4
   5

for this case but I get 对于这种情况,但我得到

Traceback (most recent call last):
File "/home/25cd3bbcc1b79793984caf14f50e7550.py", line 52, in <module>
root.child[u-2].child.append(Node(a[i]))
 IndexError: list index out of range

so I'm not getting any idea how to correct it. 所以我不知道如何纠正它。 Please provide me with correct code 请提供正确的代码给我

Let's say the user has given the list of edges as 假设用户给定的边列表为

edges =[ [3,2], [3,4], [4,5] ] 边= [[3,2],[3,4],[4,5]]

root = 2 根= 2

First, we have to convert the list of edges into a proper dictionary which will indicate the tree structure of the given edges. 首先, 我们必须将边列表转换为适当的字典 ,该字典将指示给定边的树结构。 Following is the code that I found on StackOverflow . 以下是我在StackOverflow上找到的代码。

def createDict(edges, root):
    graph ={}
    for x,y in es:
        graph.setdefault(x,set()).add(y)
        graph.setdefault(y,set()).add(x)
    tree, stack = {}, [s]
    while stack:
        parent = stack.pop()
        children = graph[parent] - tree.keys()
        tree[parent] = list(children)
        stack.extend(children)
    for i in tree.keys():
        if tree[i] == []:    #if the node is leaf node, give it a 0 val
           tree[i].append(0)   
    return tree

The output will be : tree = { 2: [3], 3: [4], 4: [5], 5: [0] } 输出将是:tree = {2:[3],3:[4],4:[5],5:[0]}

Now we will make it into a Tree structure using class Node . 现在,我们将使用Node类将其变为Tree结构 This code is written by me. 这段代码是我写的。

class Node:
     def __init__(self, val):
         self.val = val
         self.children = []  

def createNode(tree, root,b=None, stack=None):
    if stack is None:
        stack = []           #stack to store children values
        root = Node(root)    #root node is created
        b=root               #it is stored in b variable 
    x = root.val             # root.val = 2 for the first time
   if len(tree[x])>0 :       # check if there are children of the node exists or not
      for i in range(len(tree[x])):   #iterate through each child
          y = Node(tree[x][i])        #create Node for every child
          root.children.append(y)     #append the child_node to its parent_node
          stack.append(y)             #store that child_node in stack
          if y.val ==0:     #if the child_node_val = 0 that is the parent = leaf_node 
             stack.pop()    #pop the 0 value from the stack
      if len(stack):        #iterate through each child in stack
          if len(stack)>=2:      #if the stack length >2, pop from bottom-to-top
              p=stack.pop(0)     #store the popped val in p variable
          else:
              p = stack.pop()    #pop the node top_to_bottom
      createNode(tree, p,b,stack)   # pass p to the function as parent_node 
return b                            # return the main root pointer

In this code, b is just a variable that will point to the root node, so that we can iterate through it level wise and print it. 在这段代码中,b只是一个指向根节点的变量,因此我们可以逐级迭代并打印它。

For level-order Printing: 对于级别顺序打印:

def printLevel(node):
    if node is None:
        return
    queue = []
    queue.append(node)
    while(len(queue)>0):
         n =len(queue)
         while(n>0):
             p = queue[0]
             queue.pop(0)
             if p.val !=0:           #for avoiding the printing of '0'
                print(p.val, end='  ')
                for ind, value in enumerate(p.children):
                      queue.append(value)
             n -= 1
         print(" ")

Output is: 输出为:

       2
       3
       4
       5  #each level is getting printed

I don't know right now, how to print it in a slanted way ): Still working on it 我现在不知道,如何以倾斜的方式打印它):仍在处理

Well, I am not a pro in Python, just a beginner. 好吧,我不是Python的专业人士,只是一个初学者。 Corrections and modification are highly welcomed. 更正和修改非常受欢迎。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM