数据结构-树
1. 定义:
树是一种分层数据结构,由节点组成。每棵树有一个根节点,每个节点除了根节点外都恰有一个父节点,并可能有多个子节点。它是一种非线性数据结构,用于表示具有层级关系的数据。
class TreeNode:
def __init__(self, data):
self.data = data
self.children = []
2. 术语:
关键术语包括根节点(树的顶端节点)、子节点(从另一个节点延伸的节点)、叶节点(没有子节点的节点)、深度(从根节点到特定节点的路径长度)、高度(树中节点的最大深度)。
3. 类型:
树的类型多种多样,包括二叉树(每个节点最多有两个子节点)、平衡树(如AVL树,确保任何时候左右子树的高度差不超过一)、搜索树(如二叉搜索树,左子树节点值小于父节点,右子树节点值大于父节点),等等。
4. 操作:
常见的树操作包括插入、删除、遍历(如前序、中序、后序和层次遍历)等。不同类型的树有其特定的操作方式和用途。
class TreeNode:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
class BinaryTree:
def __init__(self):
self.root = None
def insert(self, key):
if not self.root:
self.root = TreeNode(key)
else:
self._insert_recursively(self.root, key)
def _insert_recursively(self, node, key):
if key < node.key:
if node.left is None:
node.left = TreeNode(key)
else:
self._insert_recursively(node.left, key)
elif key > node.key:
if node.right is None:
node.right = TreeNode(key)
else:
self._insert_recursively(node.right, key)
# 如果 key 已经存在于树中,则不进行任何操作
def delete(self, key):
self.root = self._delete_recursively(self.root, key)
def _delete_recursively(self, node, key):
if node is None:
return node
if key < node.key:
node.left = self._delete_recursively(node.left, key)
elif key > node.key:
node.right = self._delete_recursively(node.right, key)
else:
if node.left is None:
return node.right
elif node.right is None:
return node.left
# 找到右子树的最小节点,将其替换到当前节点
node.key = self._min_value_node(node.right).key
node.right = self._delete_recursively(node.right, node.key)
return node
def _min_value_node(self, node):
current = node
while current.left is not None:
current = current.left
return current
def preorder_traversal(self):
return self._preorder_recursively(self.root)
def _preorder_recursively(self, node):
if node is not None:
print(node.key, end=" ")
self._preorder_recursively(node.left)
self._preorder_recursively(node.right)
def inorder_traversal(self):
return self._inorder_recursively(self.root)
def _inorder_recursively(self, node):
if node is not None:
self._inorder_recursively(node.left)
print(node.key, end=" ")
self._inorder_recursively(node.right)
def postorder_traversal(self):
return self._postorder_recursively(self.root)
def _postorder_recursively(self, node):
if node is not None:
self._postorder_recursively(node.left)
self._postorder_recursively(node.right)
print(node.key, end=" ")
def level_order_traversal(self):
if self.root is None:
return
queue = [self.root]
while queue:
node = queue.pop(0)
print(node.key, end=" ")
if node.left is not None:
queue.append(node.left)
if node.right is not None:
queue.append(node.right)
# 测试代码
def main():
bst = BinaryTree()
keys = [10, 5, 15, 3, 7, 12, 18]
for key in keys:
bst.insert(key)
print("Preorder Traversal:")
bst.preorder_traversal()
print("\nInorder Traversal:")
bst.inorder_traversal()
print("\nPostorder Traversal:")
bst.postorder_traversal()
print("\nLevel-order Traversal:")
bst.level_order_traversal()
# 删除节点
bst.delete(10)
print("\nAfter deleting 10:")
bst.inorder_traversal()
if __name__ == "__main__":
main()
二叉搜索树(Binary Search Tree),它是一种特殊类型的树,具有以下特点:
- 每个节点最多有两个子节点:左子节点和右子节点。
- 左子节点的值小于父节点的值,右子节点的值大于父节点的值。
- 这种有序性质使得插入、删除、搜索等操作的时间复杂度可以达到 O(log n)。
提供了以下操作:
- 插入(insert):向树中插入一个新节点。
def insert(self, key):
if not self.root:
self.root = TreeNode(key)
else:
self._insert_recursively(self.root, key)
- 删除(delete):从树中删除一个指定节点。
def delete(self, key):
self.root = self._delete_recursively(self.root, key)
- 前序遍历(preorder traversal):先访问根节点,然后递归地遍历左子树和右子树。
def preorder_traversal(self):
return self._preorder_recursively(self.root)
- 中序遍历(inorder traversal):先递归地遍历左子树,然后访问根节点,最后递归地遍历右子树。这种遍历方式可以将树的所有节点按照升序排列。
def inorder_traversal(self):
return self._inorder_recursively(self.root)
- 后序遍历(postorder traversal):先递归地遍历左子树和右子树,然后访问根节点。
def postorder_traversal(self):
return self._postorder_recursively(self.root)
- 层次遍历(level-order traversal):从上到下逐层遍历树的节点。
def level_order_traversal(self):
if self.root is None:
return
queue = [self.root]
while queue:
node = queue.pop(0)
print(node.key, end=" ")
if node.left is not None:
queue.append(node.left)
if node.right is not None:
queue.append(node.right)
- 应用:
树在计算机科学中有广泛应用,如用于表示家族谱系、组织结构图、数据索引结构(如数据库中的B树和B+树)、决策流程(如决策树)等。