数据结构 - python如何递归生成树?

 花儿在绽放2502857073 发布于 2022-10-29 12:21
class Tree:
    def __init__(self, label):
        self.root = label
        self.child = {}

    def set_child(self, label, relate):
        self.child[label] = relate

    def get_root(self):
        return self.root

    def get_child(self):
        return self.child

这么一颗树结构,该如何写

def create_tree():
    create_tree()

来调用树结构递归生成树呢?
如果把对象写在递归函数里,每次都会初始化,所以不行,如果写在函数外面,又无法访问到树的对象,该如何写呢?
还是只能使用字典来生成树?

我尝试使用了

def create_tree():
    tree = Tree()

显示是必须传入参数,如果传参,又回初始化树结构,求高人指点

3 个回答
  • https://segmentfault.com/n/13...

    2022-11-12 01:46 回答
  • 大概这样写:

    #!/usr/bin/env python
    # encoding: utf-8
    
    class Tree(object):
        def __init__(self, label):
            self.value = label
            self.child = {}
    
        def add_child(self, label, relate):
            # self.child.append(Tree())
            self.child[label] = Tree(relate)
    
        def get_value(self):
            return self.value
    
        def get_child(self):
            return self.child
    
    
    def travelsal(tree):
        li = [tree]
        while True:
            try:
                t = li.pop()
                print t.get_value()
                child = t.get_child()
                if child:
                    li.extend(child.values())
            except:
                break
    
    
    def create_tree():
        root = Tree('root')
        root.add_child('c_key1', 'child_1')
        root.add_child('c_key2', 'child_2')
        print root.get_child()
        travelsal(root)
    
    
    def main():
        create_tree()
    
    if __name__ == "__main__":
        main()
    
    2022-11-12 01:46 回答
  • 好像比較懂你的意思了, 試寫了一個 Tree, 不知道你覺得怎麼樣XD

    class Tree:
    
        def __init__(self, name):
            self.name = name
            self.children = {}
    
        def __iter__(self):
            return iter(self.children)
    
        def __str__(self):
            return self.name
    
        def __repr__(self):
            return 'Tree("{}")'.format(self.name)
    
        def relationiter(self):
            yield from self.children.items()
    
        def add_child(self, child, relation):
            self.children[child] = relation
            return child
    
        def dfs(self, include_self=True):
            if include_self:
                yield self
            for child in self.children:
                yield child
                yield from child.dfs(False)
    
        def bfs(self, include_self=True):
            if include_self:
                yield self
            trees = list(self.children.keys())
            while True:
                if not trees:
                    break
                tree = trees.pop(0)
                yield tree
                trees += list(tree.children.keys())

    import and create tree:

    In [1]: from tree import Tree
    
    In [2]:     root = Tree('root')
       ...: 
       ...:     t11 = root.add_child(Tree('t11'), 30)
       ...:     t12 = root.add_child(Tree('t12'), 40)
       ...: 
       ...:     t21 = t11.add_child(Tree('t21'), 15)
       ...:     t22 = t11.add_child(Tree('t22'), 10)
       ...:     t23 = t11.add_child(Tree('t23'), 35)
       ...: 
       ...:     t24 = t12.add_child(Tree('t24'), 20)
       ...: 

    測試 __str____repr__:

    In [3]: root
    Out[3]: Tree("root")
    
    In [4]: print(root)
    root

    測試 iterator 和 relation iterator:

    In [5]: for child in root:
       ...:     print(child)
       ...:     
    t12
    t11
    
    In [6]: for child, relation in root.relationiter():
       ...:     print(child, relation)
       ...:     
    t12 40
    t11 30

    測試 dfs 和 bfs:

    In [7]: for tree in root.dfs(include_self=True):
       ...:     print(tree)
       ...:     
    root
    t12
    t24
    t11
    t21
    t22
    t23
    
    In [8]: for tree in root.bfs(include_self=True):
       ...:     print(tree)
       ...:     
    root
    t12
    t11
    t24
    t21
    t22
    t23

    這邊還有一個問題是, 不知道你原始的資料長甚麼樣子, 所以我無法猜測你怎麼 create tree。

    如果是手動一個一個加入 child 的話應該就像上面那樣, create 跟 recursion 沒什麼關係, traverse 的時候才跟 recursion 有關。

    除非你有一個對應於 tree 結構的資料, 字典, json 之類的, 然後你想要依資料自動生成, 可能這種情況才會用 recursion 來 build tree。


    因為我對於你實際的輸入不是很了解, 但是我猜你想問的是下面這件事情, 我舉個想像的例子說明這一點, 假設我們的原始資料長這樣:

        data = { 
            't11': {
                'relation': 30,
                'sub': {
                    't21': {
                        'relation': 15
                    },
                    't22': {
                        'relation': 10
                    },
                    't23': {
                        'relation': 35
                    }
                }
            },
            't12': {
                'relation': 40,
                'sub': {
                    't24': {
                        'relation': 20
                    },
                }
            }
        }

    我必須要將這樣子的資料建出一個 Tree 來, 這邊的確就跟 recursion 有關了, 首先我在 Tree 中增加一個 classmethod:

        @classmethod
        def from_data(cls, name, data):
            tree = cls(name)
            if data:
                for subname, subdata in data.items():
                    tree.add_child(
                        cls.from_data(subname, subdata.get('sub', None)),
                        subdata['relation'])
            return tree

    接著我可以用下面這種方式 recursive 地 create tree:

    root = Tree.from_data('root', data)

    測試:

    for tree in root.bfs():
        print(tree)
        for child, relation in tree.relationiter():
            print('    {}-{}'.format(child, relation))

    結果:

    root
        t12-40
        t11-30
    t12
        t24-20
    t11
        t21-15
        t23-35
        t22-10
    t24
    t21
    t23
    t22

    P.S. 有問題歡迎討論!


    我回答過的問題: Python-QA

    2022-11-12 01:46 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有