📅  最后修改于: 2023-12-03 14:46:37.534000             🧑  作者: Mango
二叉搜索树(Binary Search Tree)是一种重要的数据结构,它是以树的形式实现的数据结构,其中每个节点都包含一个关键值和两个子节点。BST的特点是,对于树上的任何节点,其左子树中的值小于该节点的值,而其右子树中的值大于该节点的值。这种排序方式使得BST易于搜索和排序。
Python提供了多种实现BST的方式,下面我们将介绍其中几种常见的实现方式。
bisect
bisect
模块提供了对已排序的序列执行二分查找和插入操作的支持。我们可以使用它来实现一个简单的BST。下面是一个示例代码片段:
import bisect
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
def insert(self, value):
if value < self.value:
if self.left is None:
self.left = Node(value)
else:
self.left.insert(value)
elif value > self.value:
if self.right is None:
self.right = Node(value)
else:
self.right.insert(value)
def inorder_traversal(self):
if self.left:
for node in self.left.inorder_traversal():
yield node
yield self
if self.right:
for node in self.right.inorder_traversal():
yield node
class BST:
def __init__(self):
self.root = None
def insert(self, value):
if self.root is None:
self.root = Node(value)
else:
self.root.insert(value)
def inorder_traversal(self):
if self.root:
return self.root.inorder_traversal()
else:
return iter([])
# 示例用法
bst = BST()
bst.insert(5)
bst.insert(3)
bst.insert(7)
bst.insert(1)
bst.insert(4)
bst.insert(6)
bst.insert(8)
for node in bst.inorder_traversal():
print(node.value)
说明:
Node
类表示BST的一个节点,包括节点值value
,以及左、右子节点left
和right
BST
类包含一个根节点root
,并提供插入操作insert
和中序遍历操作inorder_traversal
insert
方法首先判断是否有根节点,如果没有则将该值作为根节点;否则递归调用Node
类的insert
方法inorder_traversal
方法使用生成器实现中序遍历,并返回一个生成器对象。如果根节点为空,则返回一个空的迭代器优点:
缺点:
heapq
heapq
模块提供了基于堆(heap)操作的支持,它可以用于实现一个简单的BST。下面是一个示例代码片段:
import heapq
class Node:
def __init__(self, value):
self.value = value
self.parent = None
self.left = None
self.right = None
def __lt__(self, other):
return self.value < other.value
def __eq__(self, other):
return self.value == other.value
class BST:
def __init__(self):
self.heap = []
def insert(self, value):
node = Node(value)
heapq.heappush(self.heap, node)
while len(self.heap) > 1:
n1, n2 = heapq.heappop(self.heap), heapq.heappop(self.heap)
parent = Node(n1.value + n2.value)
parent.left, parent.right = n1, n2
n1.parent, n2.parent = parent, parent
heapq.heappush(self.heap, parent)
def inorder_traversal(self):
if self.heap:
return self.heap[0].inorder_traversal()
else:
return iter([])
def __len__(self):
return len(self.heap)
class HuffmanNode(Node):
def __init__(self, value, char=None):
super().__init__(value)
self.char = char
def __repr__(self):
return f"HuffmanNode(value={self.value}, char='{self.char}')"
def inorder_traversal(self):
if self.left:
for node in self.left.inorder_traversal():
yield node
yield self
if self.right:
for node in self.right.inorder_traversal():
yield node
# 示例用法
bst = BST()
text = "hello world"
freq = {char: text.count(char) for char in set(text)}
for char, f in freq.items():
node = HuffmanNode(f, char)
bst.insert(node)
for node in bst.inorder_traversal():
if node.char is not None:
print(f"{node.char} => {node.value}")
说明:
Node
类表示BST的一个节点,包括节点值value
,以及父、左、右子节点parent
、left
和right
BST
类包含一个堆heap
,并提供插入操作insert
和中序遍历操作inorder_traversal
__lt__
和__eq__
方法是用于堆排序的比较方法,表示一个节点小于(或等于)另一个节点inorder_traversal
方法使用生成器实现中序遍历,并返回一个生成器对象。如果堆为空,则返回一个空的迭代器优点:
缺点:
dataclasses
dataclasses
模块提供了数据类(data class)的支持,在Python3.7及以上版本中可以使用。我们可以使用数据类来实现一个简单的BST。下面是一个示例代码片段:
from dataclasses import dataclass
@dataclass
class Node:
value: int
left: "Node" = None
right: "Node" = None
def insert(self, value):
if value < self.value:
if self.left is None:
self.left = Node(value)
else:
self.left.insert(value)
elif value > self.value:
if self.right is None:
self.right = Node(value)
else:
self.right.insert(value)
def inorder_traversal(self):
if self.left:
for node in self.left.inorder_traversal():
yield node
yield self
if self.right:
for node in self.right.inorder_traversal():
yield node
@dataclass
class BST:
root: Node = None
def insert(self, value):
if self.root is None:
self.root = Node(value)
else:
self.root.insert(value)
def inorder_traversal(self):
if self.root:
return self.root.inorder_traversal()
else:
return iter([])
# 示例用法
bst = BST()
bst.insert(5)
bst.insert(3)
bst.insert(7)
bst.insert(1)
bst.insert(4)
bst.insert(6)
bst.insert(8)
for node in bst.inorder_traversal():
print(node.value)
说明:
Node
和BST
类上使用了@dataclass
装饰器,该装饰器自动为类生成__init__
和__repr__
方法Node
类表示BST的一个节点,包括节点值value
,以及左、右子节点left
和right
BST
类包含一个根节点root
,并提供插入操作insert
和中序遍历操作inorder_traversal
inorder_traversal
方法使用生成器实现中序遍历,并返回一个生成器对象。如果根节点为空,则返回一个空的迭代器优点:
__init__
和__repr__
方法的实现,使得代码更加简洁缺点: