打印排列树python3

时间:2018-03-27 17:47:57

标签: python-3.x permutation

我有数字列表,我需要创建树并打印所有排列,例如对于[1, 2, 3],它应该打印 123 132 213 231 312 321
目前我的代码只打印第一个元素一次:
123 32 213 31 312 21
我该如何解决?

    class Node(object):
    def __init__(self):
        self.children = None
        self.data = None
        self.depth = None


class PermutationTree(object):
    def __init__(self, numbers):
        numbers = list(set(numbers))
        numbers.sort()
        self.depth = len(numbers)
        self.tree = self.generate_root(numbers)
        self.create_tree(numbers, self.tree.children,  1)

    def generate_root(self, numbers):
        root = Node()
        root.children = []
        root.depth = 0
        for i in numbers:
            tree = Node()
            tree.data = i
            tree.depth = 1
            root.children.append(tree)
        return root

    def create_tree(self, numbers, children, depth):
        depth += 1
        if depth == self.depth + 1:
            return
        for child in children:
            reduced_numbers = list(numbers)
            reduced_numbers.remove(child.data)
            child.children = []
            for j in reduced_numbers:
                tree = Node()
                tree.data = j
                tree.depth = depth
                child.children.append(tree)
            self.create_tree(reduced_numbers, child.children, depth)

    def print_tree(self):
        self.print(self.tree)

    def print(self, node):
        for i in node.children:
            print(i.data, end="")
            if not i.depth == self.depth:
                self.print(i)
                print("")

test = [1, 2, 3]
permutation_tree = PermutationTree(test)
permutation_tree.print_tree()

1 个答案:

答案 0 :(得分:1)

这是一个很好的例子,说明为什么side effects应该在尽可能少的地方完成。

无处不在的副作用

你的方法是这样的:“我会在每次需要时打印一个数字。”这种方法可以让你对副作用进行有限的控制。您的代码在不同的递归深度中打印很多次,并且很难跟踪发生的情况。

在尽可能少的地方产生副作用

解决这个问题的另一种方法是在一个地方创造副作用。 “我将首先生成所有排列,然后打印它们。”这样的代码更容易调试,可以让您更好地控制代码中发生的事情。

如果您编写如下代码:

def print_tree(self): # this function takes care about printing
    for path in self.generate_path(self.tree):
        print(path)



def generate_perm(self, node): #this function takes care about generating permutations
    if not node.children: 
        return [str(node.data)]
    app_str = str(node.data) if node.data else ""
    res= []
    for child in node.children:
        for semi_path in self.generate_perm(child):
            res.append (app_str + semi_path)
    return res

P.S。 使用yields可以重写generate_perm以提高效率。