赞
踩
目录
树是由节点和边组成的非线性数据结构。其结构可以用来表示层次关系,例如文件系统的目录结构、公司的组织架构等。本文用python来实现一颗通用树,可以用于构建任何类型的树,如二叉树、多叉树等。
- from typing import Generic, TypeVar, List
- T = TypeVar('T')
从
typing
模块导入了Generic
、TypeVar
和List
。其中,Generic
是一个泛型基类,可以用来定义泛型类型,TypeVar
则用于定义类型变量,List
是一个泛型类型,表示列表。接着,定义了一个类型变量
T
,用于表示节点存储的值的类型。
- class Node(Generic[T]):
- _value: int
- _parent: 'Node[T]'
- _children: List['Node[T]']
- _subtree_size: int
定义了一个类
Node
,并使用Generic[T]
表示它是一个泛型类,类型参数为T
。在类中定义了四个属性,分别是
_value
、_parent
、_children
和_subtree_size
。其中,_value
用于存储节点的值,_parent
用于存储节点的父节点,_children
用于存储节点的子节点列表,_subtree_size
用于存储节点的子树大小。
__init__
方法 - def __init__(self, value: T) -> None:
- self._value = value
- self._parent = None
- self._children = []
- self._subtree_size = 1
用于初始化节点实例。该方法接收一个参数
value
,用于设置节点的值。在方法中,将节点的值、父节点、子节点列表和子树大小都设置为默认值。
- def get_value(self) -> T:
- return self._value
-
- def set_value(self, value: T) -> None:
- self._value = value
- def get_parent(self) -> 'Node[T]':
- return self._parent
- def get_subtree_size(self) -> int:
- return self._subtree_size
-
- def set_subtree_size(self, value: int) -> None:
- self._subtree_size = value
- def add_child(self, child: 'Node[T]') -> None:
- self._children.append(child)
- child._parent = self
-
- def get_children(self) -> List['Node[T]']:
- return self._children
-
- def num_children(self) -> int:
- return len(self._children)
- def is_internal(p: 'Node[T]') -> bool:
- return len(p._children) != 0 # 有子节点
-
- def is_external(p: 'Node[T]') -> bool:
- return len(p._children) == 0 # 无子节点
- def is_root(p: 'Node[T]') -> bool:
- return p._parent == None
- from node import Node
- from typing import Generic, TypeVar, List
-
- T = TypeVar('T')
__init__
方法 - class Tree(Generic[T]):
- _size: int
- _root: Node[T]
-
- def __init__(self, root: 'Node[T]') -> None:
- self._root = root
- self._size = 0
- if root != None:
- self._size = 1
在类中定义了两个属性,分别是
_size
和_root
。其中,_size
用于存储树的节点数,_root
用于存储树的根节点。
在__init__
方法中接收一个参数root
,用于设置树的根节点。在方法中,将根节点和节点数都设置为默认值。如果根节点不为空,则将节点数设置为 1。
- def get_root(self) -> 'Node[T]':
- return self._root
-
- def get_size(self) -> int:
- return self._size
- def is_empty(self) -> bool:
- return self._root == None
-
- def is_root(self, p: 'Node[T]') -> bool:
- if p is None:
- return False
- return p.get_parent() == None
- def is_leaf(self, p: 'Node[T]') -> bool:
- if p is None:
- return False
- return p.is_external()
- def add_node(self, p: 'Node[T]', parent: 'Node[T]') -> None:
- if self._root is None and p != None and parent is None:
- self._root = p
- self._size += 1
-
- elif (p is None) or (parent is None):
- return
-
- else:
- parent.add_child(p)
- self._size += 1
-
- # Update subtree size for parent and all its ancestors.
- while p.get_parent() != None:
- p = p.get_parent()
- p_subtree = p.get_subtree_size()
- p.set_subtree_size(p_subtree + 1)
-
- def remove_node(self, p: 'Node[T]') -> None:
- if p is None:
- return
-
- if p.is_root():
- self._root = None
- self._size = 0
- else:
- current = p
- subtree_size = p.get_subtree_size()
- while p.get_parent() != None:
- p = p.get_parent()
- p.set_subtree_size(p.get_subtree_size() - subtree_size)
- parent = current.get_parent()
- parent.get_children().remove(current)
- self._size -= subtree_size

add_node用于添加节点。它接受两个参数
p
和parent
,将节点p
添加为parent
的子节点。如果树为空,则将p
设置为根节点。如果p
或parent
为空,则不进行任何操作。添加节点后,会更新其父节点及其所有祖先节点的子树大小(即_subtree_size
属性)。remove_node用于删除节点。它接受一个参数
p
,表示要删除的节点。如果节点p
为空,则不进行任何操作。如果节点p
是根节点,则将树清空。否则,删除节点并更新其父节点及其所有祖先节点的子树大小。
- def preorder(self, p: 'Node[T]', ls: List['Node[T]']) -> None:
- if p is None:
- return
-
- ls.append(p)
- for child in p._children:
- self.preorder(child, ls)
-
- def postorder(self, p: 'Node[T]', ls: List['Node[T]']) -> None:
- if p is None:
- return
-
- for child in p._children:
- self.postorder(child,ls)
- ls.append(p)
这是一个基本的树的实现,可以基于这个树实现有具体要求的树。
如果文中有什么错误欢迎大家留言指出,如果帮助到你的话可以小小的三连一波!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。