首先下载treelib库
pip install treelib
然后引入Tree、Node类,Tree包含一些树的操作(如插入节点,返回树的深度等),Node包含树节点的基本信息(节点node的基本信息是Node(tag(标签),identifier(节点id,是唯一的,不指定值的话系统自动分配,且与tag一样的值),data(数据)),tag,identifier,data可以独立访问)。
from treelib inport Tree, Node
下面开始介绍一下它的基本操作:
1、构建树(无论是二叉树还是多叉树都treelib支持,只要按自己的逻辑插入节点即可)
有:
create_node(self, tag=None, identifier=None, parent=None, data=None)
和:
add_node(self, node, parent=None)两个方法,
方法一:
tree = Tree() #初始化树
tree.create_node(tag='root', identifier='root', data =3); //根节点
tree.create_node('child', 'child', parent ='root', data=2);//类似这样插入子节点
方法二
tree = Tree()
rootnode = Node(tag=0, identifier= 0) #先创建一个Node节点
childnode = Node(tag = 1, identifier = 1) #identifier在树中必须唯一。如果不指定值,系统会自动分配
tree.add_node(rootnode) # 根节点
tree.add_node(childnode, parent = rootnode) #指定父节点
2、打印树
tree.show() # 或print(tree) 用树结构来显示,显示的数据是 tag 的数据
3、删除操作
# 删除子树
tree.remove_node(identifier) #输入节点ID,删除以该节点为根的子树,并返回被删除的节点数量
##或者
tree.remove_subtree(nid) #传入节点ID即可,删除以该节点为根的子树,并返回被删的子树
# 删除单个节点
tree.link_past_node(nid) # 传入节点,将该节点的子节点接入该节点的父节点,然后删除该节点
4、统计叶子节点的数量
tree.leaves(nid=None) # 不指定参数则返回树所有的叶子节点数量,指定节点则返回以该节点为根的子树的所有叶子节点
5、统计树所有节点数量
tree.len() # 返回树所有节点的数量
##或者是
tree.size(level = None) # 默认是统计所有节点的数量,如果传入树的第level层,则返回level层的节点数量
6、返回节点所在的层数
tree.level(identifier) # 传入节点的ID,返回该节点所在的层数
##或者
tree.depth(node=Node) # 不指定参数,返回树的高度,指定节点返回节点所在高度
7、根节点到某一节点的路径
tree.rsearch(identifier) # 传入节点ID,以列表返回从该节点到根节点的路径
8、根节点到所有叶子节点的路径
tree.paths_to_leaves() # 以列表嵌套列表形式返回每一条根节点到叶子节点的路径,一条路径为一个列表
9、返回全部节点
tree.all_nodes() # 按树结构顺序返回全部节点,返回结果是列表
###或者
tree.all_nodes_itr() # 按树结构顺序返回全部节点,返回结果是迭代器
###或者
tree.expand_tree() # 按树深度优先遍历返回全部节点,返回结果是生成器
10、返回某一节点的子节点
tree.children(nid) # 传入节点ID,以列表形式返回子节点(node类),无子节点返回空列表
###或者
tree.is_branch(nid) # 传入节点ID,以列表返回子节点(identifier的值),无子节点返回空列表
11、返回兄弟节点和父节点
# 返回父节点
tree.parent(nid) # 传入节点ID,返回该节点父节点,如果是根节点返回None
# 返回兄弟节点
tree.siblings(nid) # 传入节点ID,返回该节点兄弟节点,无返回空
12、祖宗节点
tree.ancestor(nid, level=None) # 传入节点ID,返回该节点的前一个祖宗节点。如果再传入该节点的当前层数level,则返回该节点上一层的节点
tree.tree.is_ancestor(ancestor,grandchild) # 传入两个节点,如果ancestor是grandchild的祖宗,返回True,否则返回False
13、获取节点、修改节点、判断节点是否在树中
# 获取节点
tree.get_node(nid)
# 修改节点数据
tree.update_node(nid, *attr) # 传入节点和修改参数,如tree.update_node('node1',data=1) #修改节点node1 的data数据为1
#判断节点是否在树中
tree.contains(nid) # 在树中返回True,不在返回False
14、子树转接操作
tree.move_node(source,destination) # 传入两个节点,将节点source的子节点移为destination的子节点
15、两树合并
tree.paste(nid,new_tree,deep=False) # 传入节点和新树,将新树直接插入该节点下
tree.merge(nid,new_tree,deep=False) # 传入节点和新树,将新树根节点下的子树插入到该节点中,删除新树根节点
16、拷贝
tree.subtree(nid) # 传入节点,拷贝以该节点为根的子树
17、保存多叉树
# 保存为字典形式
tree.to_dict()
# 保存为json格式
tree.to_json()
# 转换为图结构
tree.to_graphviz()
# 保存到特定文件
tree.save2file(filename)
最后在使用Treelib辅助构造树时,虽然这些方法都是返回Node类型的字典或类别,但是可以通过Node的基本信息(如tag,identifier,data)去访问具体的数据,也可以通过这些信息间接去完成自己需要做的任务。
最后可以看下官方文档。