树的基本概念
树是一种非线性的数据结构,由节点和边组成。每个节点包含一个值和指向子节点的指针。树结构具有层次性,最顶层的节点称为根节点,没有子节点的节点称为叶子节点。
树的基本术语包括:
- 根节点:树的顶层节点,没有父节点。
- 子节点:一个节点的直接后继节点。
- 父节点:一个节点的直接前驱节点。
- 叶子节点:没有子节点的节点。
- 深度:从根节点到当前节点的路径长度。
- 高度:从当前节点到叶子节点的最长路径长度。
二叉树的基本概念
二叉树是一种特殊的树结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树具有以下特性:
- 每个节点最多有两个子节点。
- 左子节点和右子节点是有序的,不能随意交换。
二叉树的常见类型包括:
- 满二叉树:所有非叶子节点都有两个子节点,且所有叶子节点都在同一层。
- 完全二叉树:除了最后一层,其他层都是满的,且最后一层的节点都集中在左侧。
二叉树的实现
以下是二叉树的Python实现:
class TreeNode:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
class BinaryTree:
def __init__(self, root_value):
self.root = TreeNode(root_value)
def insert_left(self, parent_node, value):
if parent_node.left is None:
parent_node.left = TreeNode(value)
else:
new_node = TreeNode(value)
new_node.left = parent_node.left
parent_node.left = new_node
def insert_right(self, parent_node, value):
if parent_node.right is None:
parent_node.right = TreeNode(value)
else:
new_node = TreeNode(value)
new_node.right = parent_node.right
parent_node.right = new_node
def traverse_inorder(self, node):
if node is not None:
self.traverse_inorder(node.left)
print(node.value, end=' ')
self.traverse_inorder(node.right)
def traverse_preorder(self, node):
if node is not None:
print(node.value, end=' ')
self.traverse_preorder(node.left)
self.traverse_preorder(node.right)
def traverse_postorder(self, node):
if node is not None:
self.traverse_postorder(node.left)
self.traverse_postorder(node.right)
print(node.value, end=' ')
# 示例用法
tree = BinaryTree(1)
tree.insert_left(tree.root, 2)
tree.insert_right(tree.root, 3)
tree.insert_left(tree.root.left, 4)
tree.insert_right(tree.root.left, 5)
print("Inorder traversal:")
tree.traverse_inorder(tree.root)
print("\nPreorder traversal:")
tree.traverse_preorder(tree.root)
print("\nPostorder traversal:")
tree.traverse_postorder(tree.root)
二叉树的遍历
二叉树的遍历方式主要有三种:
- 前序遍历:根节点 -> 左子树 -> 右子树
- 中序遍历:左子树 -> 根节点 -> 右子树
- 后序遍历:左子树 -> 右子树 -> 根节点
以下是三种遍历方式的非递归实现:
def preorder_iterative(root):
stack = [root]
while stack:
node = stack.pop()
if node:
print(node.value, end=' ')
stack.append(node.right)
stack.append(node.left)
def inorder_iterative(root):
stack = []
current = root
while stack or current:
while current:
stack.append(current)
current = current.left
current = stack.pop()
print(current.value, end=' ')
current = current.right
def postorder_iterative(root):
stack = []
last_visited = None
current = root
while stack or current:
while current:
stack.append(current)
current = current.left
peek_node = stack[-1]
if peek_node.right and last_visited != peek_node.right:
current = peek_node.right
else:
print(peek_node.value, end=' ')
last_visited = stack.pop()
二叉搜索树
二叉搜索树(BST)是一种特殊的二叉树,对于每个节点:
- 左子树的所有节点值都小于当前节点值
- 右子树的所有节点值都大于当前节点值
以下是BST的实现:
class BST:
def __init__(self):
self.root = None
def insert(self, value):
if self.root is None:
self.root = TreeNode(value)
else:
self._insert_recursive(self.root, value)
def _insert_recursive(self, node, value):
if value < node.value:
if node.left is None:
node.left = TreeNode(value)
else:
self._insert_recursive(node.left, value)
else:
if node.right is None:
node.right = TreeNode(value)
else:
self._insert_recursive(node.right, value)
def search(self, value):
return self._search_recursive(self.root, value)
def _search_recursive(self, node, value):
if node is None or node.value == value:
return node
if value < node.value:
return self._search_recursive(node.left, value)
return self._search_recursive(node.right, value)
def delete(self, value):
self.root = self._delete_recursive(self.root, value)
def _delete_recursive(self, node, value):
if node is None:
return node
if value < node.value:
node.left = self._delete_recursive(node.left, value)
elif value > node.value:
node.right = self._delete_recursive(node.right, value)
else:
if node.left is None:
return node.right
if node.right is None:
return node.left
temp = self._min_value_node(node.right)
node.value = temp.value
node.right = self._delete_recursive(node.right, temp.value)
return node
def _min_value_node(self, node):
current = node
while current.left is not None:
current = current.left
return current
# 示例用法
bst = BST()
bst.insert(50)
bst.insert(30)
bst.insert(20)
bst.insert(40)
bst.insert(70)
bst.insert(60)
bst.insert(80)
print("\nBST Inorder traversal:")
bst._inorder_recursive(bst.root)
bst.delete(20)
print("\nAfter deleting 20:")
bst._inorder_recursive(bst.root)
bst.delete(30)
print("\nAfter deleting 30:")
bst._inorder_recursive(bst.root)
bst.delete(50)
print("\nAfter deleting 50:")
bst._inorder_recursive(bst.root)
平衡二叉树
平衡二叉树(AVL树)是一种自平衡的二叉搜索树,任何节点的两个子树的高度差不超过1。以下是AVL树的实现:
class AVLNode:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
self.height = 1
class AVLTree:
def insert(self, root, value):
if not root:
return AVLNode(value)
elif value < root.value:
root.left = self.insert(root.left, value)
else:
root.right = self.insert(root.right, value)
root.height = 1 + max(self.get_height(root.left),
self.get_height(root.right))
balance = self.get_balance(root)
# Left Left Case
if balance > 1 and value < root.left.value:
return self.right_rotate(root)
# Right Right Case
if balance < -1 and value > root.right.value:
return self.left_rotate(root)
# Left Right Case
if balance > 1 and value > root.left.value:
root.left = self.left_rotate(root.left)
return self.right_rotate(root)
# Right Left Case
if balance < -1 and value < root.right.value:
root.right = self.right_rotate(root.right)
return self.left_rotate(root)
return root
def left_rotate(self, z):
y = z.right
T2 = y.left
y.left = z
z.right = T2
z.height = 1 + max(self.get_height(z.left),
self.get_height(z.right))
y.height = 1 + max(self.get_height(y.left),
self.get_height(y.right))
return y
def right_rotate(self, z):
y = z.left
T3 = y.right
y.right = z
z.left = T3
z.height = 1 + max(self.get_height(z.left),
self.get_height(z.right))
y.height = 1 + max(self.get_height(y.left),
self.get_height(y.right))
return y
def get_height(self, root):
if not root:
return 0
return root.height
def get_balance(self, root):
if not root:
return 0
return self.get_height(root.left) - self.get_height(root.right)
def pre_order(self, root):
if not root:
return
print("{0} ".format(root.value), end="")
self.pre_order(root.left)
self.pre_order(root.right)
# 示例用法
avl_tree = AVLTree()
root = None
root = avl_tree.insert(root, 10)
root = avl_tree.insert(root, 20)
root = avl_tree.insert(root, 30)
root = avl_tree.insert(root, 40)
root = avl_tree.insert(root, 50)
root = avl_tree.insert(root, 25)
print("\nAVL Tree Preorder traversal:")
avl_tree.pre_order(root)
树的应用场景
树结构在计算机科学中有广泛应用:
- 文件系统:目录结构通常用树表示
- 数据库索引:B树和B+树用于高效数据检索
- 网络路由:路由表通常使用前缀树(Trie)结构
- 游戏开发:场景管理使用四叉树或八叉树
- 编译器:抽象语法树(AST)表示程序结构
- 决策树:机器学习中的分类算法
树结构的高效查找、插入和删除操作使其成为许多应用程序的基础数据结构。理解树和二叉树的基本概念及其实现方式,对于掌握更复杂的数据结构和算法至关重要。