当前位置:   article > 正文

数据结构与算法 —— 树的基本操作以及实现(python实现)_python实现树

python实现树

目录

前言

1. 实现一个通用节点类

1.1 import及声明泛型类型变量

1.2 定义类

1.3 定义__init__ 方法 

1.4 获取和设置节点的值

1.5  获取节点的父节点

1.6 获取和设置节点的子树大小

1.7 添加子节点和获取子节点列表及个数

1.8 判断内部/外部节点 

1.9 判断根节点

2. 实现一个通用树类

2.1 import及声明泛型类型变量

2.2 定义类和__init__ 方法 

2.3 获取根节点以及节点数量

2.6  判断是否为空树以及节点是否为根节点

2.7 判断是否有子节点

2.8 添加节点和移除节点

2.9 先序和后序遍历

3. 结尾


前言

树是由节点和边组成的非线性数据结构。其结构可以用来表示层次关系,例如文件系统的目录结构、公司的组织架构等。本文用python来实现一颗通用树,可以用于构建任何类型的树,如二叉树、多叉树等。


1. 实现一个通用节点类

1.1 import及声明泛型类型变量

  1. from typing import Generic, TypeVar, List
  2. T = TypeVar('T')

typing 模块导入了 GenericTypeVarList。其中,Generic 是一个泛型基类,可以用来定义泛型类型,TypeVar 则用于定义类型变量,List 是一个泛型类型,表示列表。 

接着,定义了一个类型变量 T,用于表示节点存储的值的类型。

1.2 定义类

  1. class Node(Generic[T]):
  2. _value: int
  3. _parent: 'Node[T]'
  4. _children: List['Node[T]']
  5. _subtree_size: int

定义了一个类 Node,并使用 Generic[T] 表示它是一个泛型类,类型参数为 T

在类中定义了四个属性,分别是 _value_parent_children_subtree_size。其中,_value 用于存储节点的值,_parent 用于存储节点的父节点,_children 用于存储节点的子节点列表,_subtree_size 用于存储节点的子树大小。

1.3 定义__init__ 方法 

  1. def __init__(self, value: T) -> None:
  2. self._value = value
  3. self._parent = None
  4. self._children = []
  5. self._subtree_size = 1

用于初始化节点实例。该方法接收一个参数 value,用于设置节点的值。在方法中,将节点的值、父节点、子节点列表和子树大小都设置为默认值。 

1.4 获取和设置节点的值

  1. def get_value(self) -> T:
  2. return self._value
  3. def set_value(self, value: T) -> None:
  4. self._value = value

1.5  获取节点的父节点

  1. def get_parent(self) -> 'Node[T]':
  2. return self._parent

1.6 获取和设置节点的子树大小

  1. def get_subtree_size(self) -> int:
  2. return self._subtree_size
  3. def set_subtree_size(self, value: int) -> None:
  4. self._subtree_size = value

1.7 添加子节点和获取子节点列表及个数

  1. def add_child(self, child: 'Node[T]') -> None:
  2. self._children.append(child)
  3. child._parent = self
  4. def get_children(self) -> List['Node[T]']:
  5. return self._children
  6. def num_children(self) -> int:
  7. return len(self._children)

1.8 判断内部/外部节点 

  1. def is_internal(p: 'Node[T]') -> bool:
  2. return len(p._children) != 0 # 有子节点
  3. def is_external(p: 'Node[T]') -> bool:
  4. return len(p._children) == 0 # 无子节点

1.9 判断根节点

  1. def is_root(p: 'Node[T]') -> bool:
  2. return p._parent == None

2. 实现一个通用树类

2.1 import及声明泛型类型变量

  1. from node import Node
  2. from typing import Generic, TypeVar, List
  3. T = TypeVar('T')

2.2 定义类和__init__ 方法 

  1. class Tree(Generic[T]):
  2. _size: int
  3. _root: Node[T]
  4. def __init__(self, root: 'Node[T]') -> None:
  5. self._root = root
  6. self._size = 0
  7. if root != None:
  8. self._size = 1

在类中定义了两个属性,分别是 _size_root。其中,_size 用于存储树的节点数,_root 用于存储树的根节点。

在__init__ 方法中接收一个参数 root,用于设置树的根节点。在方法中,将根节点和节点数都设置为默认值。如果根节点不为空,则将节点数设置为 1。 

2.3 获取根节点以及节点数量

  1. def get_root(self) -> 'Node[T]':
  2. return self._root
  3. def get_size(self) -> int:
  4. return self._size

2.6  判断是否为空树以及节点是否为根节点

  1. def is_empty(self) -> bool:
  2. return self._root == None
  3. def is_root(self, p: 'Node[T]') -> bool:
  4. if p is None:
  5. return False
  6. return p.get_parent() == None

2.7 判断是否有子节点

  1. def is_leaf(self, p: 'Node[T]') -> bool:
  2. if p is None:
  3. return False
  4. return p.is_external()

2.8 添加节点和移除节点

  1. def add_node(self, p: 'Node[T]', parent: 'Node[T]') -> None:
  2. if self._root is None and p != None and parent is None:
  3. self._root = p
  4. self._size += 1
  5. elif (p is None) or (parent is None):
  6. return
  7. else:
  8. parent.add_child(p)
  9. self._size += 1
  10. # Update subtree size for parent and all its ancestors.
  11. while p.get_parent() != None:
  12. p = p.get_parent()
  13. p_subtree = p.get_subtree_size()
  14. p.set_subtree_size(p_subtree + 1)
  15. def remove_node(self, p: 'Node[T]') -> None:
  16. if p is None:
  17. return
  18. if p.is_root():
  19. self._root = None
  20. self._size = 0
  21. else:
  22. current = p
  23. subtree_size = p.get_subtree_size()
  24. while p.get_parent() != None:
  25. p = p.get_parent()
  26. p.set_subtree_size(p.get_subtree_size() - subtree_size)
  27. parent = current.get_parent()
  28. parent.get_children().remove(current)
  29. self._size -= subtree_size

add_node用于添加节点。它接受两个参数 pparent,将节点 p 添加为 parent 的子节点。如果树为空,则将 p 设置为根节点。如果 pparent 为空,则不进行任何操作。添加节点后,会更新其父节点及其所有祖先节点的子树大小(即 _subtree_size 属性)。

remove_node用于删除节点。它接受一个参数 p,表示要删除的节点。如果节点 p 为空,则不进行任何操作。如果节点 p 是根节点,则将树清空。否则,删除节点并更新其父节点及其所有祖先节点的子树大小。 

2.9 先序和后序遍历

  1. def preorder(self, p: 'Node[T]', ls: List['Node[T]']) -> None:
  2. if p is None:
  3. return
  4. ls.append(p)
  5. for child in p._children:
  6. self.preorder(child, ls)
  7. def postorder(self, p: 'Node[T]', ls: List['Node[T]']) -> None:
  8. if p is None:
  9. return
  10. for child in p._children:
  11. self.postorder(child,ls)
  12. ls.append(p)

3. 结尾

这是一个基本的树的实现,可以基于这个树实现有具体要求的树。

如果文中有什么错误欢迎大家留言指出,如果帮助到你的话可以小小的三连一波!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/169521
推荐阅读
相关标签
  

闽ICP备14008679号