级别顺序遍历 - 树

时间:2017-02-13 05:47:41

标签: python python-3.x queue breadth-first-search

我需要定义一个名为level_order_travel的函数,它将树作为输出a,并按级别顺序打印列表中所有节点的列表。

以下代码显示了这一点:

def create_tree(node_list, index=1):
    if index >= len(node_list) or node_list[index] is None:
        return None
    d = node_list[index]
    l = index * 2
    r = l + 1
    tree = BinaryTree(d)
    tree.set_left(create_tree(node_list, l))
    tree.set_right(create_tree(node_list, r))
    return tree

def level_order_travel(a):
###

def test():
    list_of_leaves = [None, 10, 5, 15, None, None, 11, 22]
    my_tree = create_tree(list_of_leaves )

    print("Breadth first =", level_order_travel(my_tree))

test()

这是我的BinaryTree类:

class BinaryTree:

    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

    def get_left(self):
        return self.left

    def get_right(self):
        return self.right

    def set_left(self, tree):
        self.left = tree

    def set_right(self, tree):
        self.right = tree

    def set_data(self, data):
        self.data = data

    def get_data(self):
        return self.data

    def create_string(self, spaces): 
        info = ' ' * spaces + str(self.data) 
        if self.left != None: 
            info += '\n(l)' + self.left.create_string(spaces+4) 
        if not self.right == None: 
            info += '\n(r)' + self.right.create_string(spaces+4) 
        return info       

    def __str__(self): 
        representation = self.create_string(0) 
        return representation

这是我的队列类:

class Queue:
    def __init__(self):
        self.items = []

    def is_empty(self):
        return self.items == []

    def enqueue(self, item):
        self.items.insert(0,item)

    def dequeue(self):
        return self.items.pop()

    def size(self):
        return len(self.items)

    def peek(self):
        return self.items[self.size() - 1]

这是我到目前为止的尝试:

def level_order_travel(a):
    root = a.get_data()
    q = Queue()
    q.enqueue(root)
    list_of_leaves = []
    if root is None:
        return []
    else:
        if a.get_left() is not None:
            q.enqueue(a.get_left().get_data())
        if a.get_right() is not None:
            q.enqueue(a.get_right().get_data())
    while q.is_empty() == False:
        list_of_leaves.append(q.dequeue())
    return list_of_leaves

这应该产生以下输出:

[10, 5, 15, 11, 22] 

但它产生以下输出:

[10, 5, 15]

感谢任何帮助。谢谢。

1 个答案:

答案 0 :(得分:1)

修改您的bfs遍历函数以跟踪visited个节点,它应该适用于任何图形(不仅是非循环的图形树):

def breadth_first_traversal(a):
    if a is None:
        return []
    visited = set([])
    q = Queue()
    q.enqueue(a)
    list_of_leaves = []
    while not q.is_empty():
        a = q.dequeue()
        visited.add(a)      
        child = a.get_left()
        if child is not None and not child in visited:
            q.enqueue(child)
        child = a.get_right()
        if child is not None and not child in visited:
            q.enqueue(child)
        list_of_leaves.append(a.get_data())
    return list_of_leaves

test()
# ('Breadth first =', [10, 5, 15, 11, 22])

此外,如果您只想对tree使用该实现,那么您可以进一步简化(您不需要跟踪visited个节点,因为每个节点都保证是只访问过一次,因为每个节点只有一个父节点:

def breadth_first_traversal(a): # only for trees
    if a is None:
        return []
    q = Queue()
    q.enqueue(a)
    list_of_leaves = []
    while not q.is_empty():
        a = q.dequeue()
        child = a.get_left()
        if child is not None: 
            q.enqueue(child)
        child = a.get_right()
        if child is not None: 
            q.enqueue(child)
        list_of_leaves.append(a.get_data())
    return list_of_leaves