在Python中使用递归进行后序遍历

时间:2014-05-06 21:28:35

标签: python recursion postorder

我是python编程的新手,最近我在编程递归时遇到了一些问题。考虑到我有一个图表:a)顶点列表b)和邻接列表(作为二维列表)我正在尝试得到一个列表,它将给我这些顶点的Postorder遍历顺序(Post_Order_List_of_Node),这将反过来告诉任何节点的顺序(Order_of_Node)和所有节点的父亲列表。我写了以下代码:

我的“订单”变量是全局的,但根据输出,它不会增加。

我不知道为什么但变量“order”没有得到更新。

def Post_Order(node,order,father):
    Order_of_Node = [No_of_Nodes]*No_of_Nodes   #Initialization
    Post_Order_List_of_Node = [No_of_Nodes]*No_of_Nodes     #Initialization
    def recursive(node,order,father):
        if len(Spanning_Tree[node]) == 0:
            Order_of_Node[node] = order
            Post_Order_List_of_Node[order] = node
            order = order + 1
            Father_List[node] = father
            del(Spanning_Tree[father][0])
            return
        else:
            while(len(Spanning_Tree[node])!=0): 
            recurse(Spanning_Tree[node][0],order,node)
    recurse(node,order,father)
    return Post_Order_List_of_Node,Order_of_Node
Father_List = [0]*No_of_Nodes
root = 0
father = 0
order = 1
Order = []
Order = Post_Order(root,order,father)

1 个答案:

答案 0 :(得分:1)

order未获得更新,因为与您声称的不同,是全局变量。通过这样定义recursive函数,

def recursive(node,order,father):

在该函数范围内对order的任何引用都只会修改参数,而不是全局变量。在该函数中,您只需修改order分支中的if,但在else分支中使用它。因此,参数的更新永远不会被传递。

为了将order用作全局变量,请将其声明为:

def recursive(node, father):
    global order
    if ...

代码中的另一个问题 - 当您为Post_Order_List_of_Node设置值时,请使用

Post_Order_List_of_Node[order] = node

但是,order从1开始而不是从0开始,因此对于最后一个节点,您将收到错误。你需要使用

Post_Order_List_of_Node[order-1] = node

代替。


您可能会或可能不会注意到的一个低效率是您处理节点的方式:

def recursive(node,father):
    if len(Spanning_Tree[node]) == 0:
        # Process node
    else:
        while(len(Spanning_Tree[node])!=0): 
            # Process child

在对recursive的一次通话中,您只处理孩子节点本身。您的代码因while循环而起作用 - 您为每个有孩子的孩子调用recursive两次。您可以将其切换为执行此操作,而不是这样做:

def recursive(node,father):
    for child in Spanning_Tree[node]:
        # process child
    # process node

这具有额外的优势,即不需要修改Spanning_Tree。但是,它确实要求您确保拥有树(没有循环),或者在开始处理任何子项之前将节点标记为已访问。