简体   繁体   English

迭代前阶kary树遍历

[英]Iterative preorder k-ary tree traversal

My python code currently prints out the name of each node in a k-ary tree, from the root to leafs. 我的python代码当前打印出从根到叶子的k进制树中每个节点的名称。 However, I would like the name of branch nodes with children > 1 to print out n times; 但是,我希望子节点> 1的分支节点的名称打印n次。 where n = number of children. 其中n =孩子数。

For the above tree 对于上面的树 在此处输入图片说明

My code prints the following 我的代码显示以下内容

start
a
b
d
f
end
c
e
end
c
e
end

However, I want it to print the following 但是,我希望它打印以下内容

start
a
b
d
f
end
b
c
e
end
d
c
e
end

I want nodes b and d to print out twice (in the correct order) since they have two children. 我希望节点b和d打印两次(以正确的顺序),因为它们有两个孩子。

I feel like this is more simple than I am making it out to be. 我觉得这比我想像的要简单。 Do I need to add a list of nodes visited? 我是否需要添加已访问节点的列表? But then I would need to know the number of times visited as well? 但是,我还需要知道访问的次数吗?

One caveat is that only nodes with (n.tag == prefix + 'decision' or n.tag == prefix + 'task') will ever have more than one child. 一个警告是,只有具有(n.tag ==前缀+'决策'或n.tag ==前缀+'任务')的节点才会有多个子节点。 So, I could keep a list of decision/task nodes and the number of times they have been visited. 因此,我可以保留一个决策/任务节点及其访问次数的列表。 If the number of times visited == number of children, pop the node from the list? 如果访问次数==子节点数,请从列表中弹出节点?

I feel like I am over complicating this a lot. 我觉得我已经把这复杂化了很多。

This is a simple example, however my code needs to work for k-ary. 这是一个简单的示例,但是我的代码需要适用于kary。 (I know my example tree is only binary). (我知道我的示例树只是二进制的)。

My code is below: 我的代码如下:

from itertools import izip
import xml.etree.ElementTree as ET

def main():

    prefix = "{http://jbpm.org/4.4/jpdl}"

    xml = ET.parse("testWF2.xml")
    root = xml.getroot()
    i = root.findall('*')

    # convert list to dictionary indexed by Element.name
    temp = []
    for it in i:
        name = it.get("name")
        if (name):
            temp.append(name)
        else:
            tag = it.tag
            temp.append(tag.replace(prefix, '')) # if no name exists use tag (ex. start and end)
    b = dict(izip(temp, i)) # create the dictionary with key = name

    nodes = []
    # add root to the list
    nodes.append(b["start"])

    while(nodes):

        n = nodes.pop()
        transitions = n.findall(prefix+"transition")
        children = []
        # get all of n's children
        for t in transitions:
            children.append(b[t.get("to")])

        for child in children:
            nodes.append(child) # add child

        if (not n.get("name")):
            print ("start")
        else:
            print(n.get("name"))

    # end while loop

main()

If anyone needs to see the testWF2.xml file it is pasted here http://bpaste.net/show/160832/ 如果有人需要查看testWF2.xml文件,则将其粘贴在此处http://bpaste.net/show/160832/

For your special requirement, I changed it so that each iteration works with the parent and the child. 根据您的特殊要求,我对其进行了更改,以便每次迭代都可以与父级和子级一起使用。 The output is based on the parent - in that way the parent automatically is output k-times. 输出基于父级-这样,父级会自动输出k次。 It also needs a special case to output the child when there are no further children. 当没有其他孩子时,还需要特殊情况才能输出孩子。

from itertools import izip
import xml.etree.ElementTree as ET

def main():
    prefix = "{http://jbpm.org/4.4/jpdl}"

    xml = ET.parse("testWF2.xml")
    root = xml.getroot()
    i = root.findall('*')

    # convert list to dictionary indexed by Element.name
    temp = []
    for it in i:
        name = it.get("name")
        if name:
            temp.append(name)
        else:
            tag = it.tag
            temp.append(tag.replace(prefix, '')) # if no name exists use tag (ex. start and end)
    b = dict(izip(temp, i)) # create the dictionary with key = name


    nodes = []
    # add root to the list
    start_pair = (None, b["start"])  # # # # # using pairs
    nodes.append(start_pair)

    while(nodes):
        parent, n = nodes.pop()  # # # # # using pairs
        transitions = n.findall(prefix+"transition")
        children = []
        # get all of n's children
        for t in transitions:
            child = b[t.get("to")]
            children.append(child)
            nodes.append((n, child))  # add parent/child pair

        # only output the parent (thus outputing k times)
        try:
            print parent.get("name", "start")
        except AttributeError:
            pass  # ignore the start position
        # also output the node if it has no children (terminal node)
        if len(children) < 1:
            print n.get("name", "start")

    # end while loop

main()

start
a
b
d
f
end
d
c
e
end
b
c
e
end

Thats not a tree which you have shown in diagram. 那不是您在图中显示的树。 It is a graph. 它是一个图。 You can use DFS to print out your diagram. 您可以使用DFS打印出图表。 change the start and end nodes for each call to DFS as: 将每次对DFS的调用的起始节点和结束节点更改为:

  1. Start to end 开始到结束
  2. b to end b结束
  3. d to end d结束

I am sorry, couldn't put it in a nice table. 对不起,不能把它放在漂亮的桌子上。 I hate stack overflow which makes formatting extremely difficult. 我讨厌堆栈溢出,这使得格式化极其困难。

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

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