二分搜索树(Binary Search Tree)是一种基于节点值大小关系,具有二叉树形态和搜索能力的数据结构。在二分搜索树中,每个节点最多有两个子节点,左子节点的值小于父节点,右子节点的值大于父节点。
定义的形式
定义二分搜索树可以采用递归的方式。设根节点为root,左子树为左节点left,右子树为右节点right,则其定义为:
- root节点为空,即这是一棵空树;
- left、right节点为空,即这是一棵只包含root节点的树;
- left、right节点尽管为空,但同时也可能不为空;而当left不为空时,left子树中所有节点值均小于root节点值;当right不为空时,right子树中所有节点值均大于root节点值。
递归时,left和right也分别视为一棵二叉搜索树。这样定义不仅具有简洁性,也强调了二分搜索树的递归结构和性质。
特性
二分搜索树的特性使得它对于插入、查找等操作具有高效性。以下是二分搜索树的几个特性:
- 每个节点最多有两个子节点;
- 对于非空节点的左子树,其值小于父节点;
- 对于非空节点的右子树,其值大于父节点;
- 中序遍历(In-order Traversal)二分搜索树可以得到一个单调递增的数列。
因此,我们可以通过二分搜索树的特性在O(log n)的时间复杂度内实现插入、删除和查找操作。
实现与运用
在实现二分搜索树时,一般采用链表或数组等数据结构,也可以通过继承实现Python的二分搜索树类。插入的操作可以通过递归实现,如下:
```python
def insert(self, val: int) -> None:
if self.root is None:
self.root = TreeNode(val)
else:
self._insert(self.root, val)
def _insert(self, node: TreeNode, val: int) -> None:
if val < node.val:
if node.left:
self._insert(node.left, val)
else:
node.left = TreeNode(val)
elif val > node.val:
if node.right:
self._insert(node.right, val)
else:
node.right = TreeNode(val)
```
在查找方面,可以采用递归或迭代的方式实现。下面是递归查找的实现:
```python
def find(self, val: int) -> bool:
if self.root is None:
return False
else:
return self._find(self.root, val)
def _find(self, node: TreeNode, val: int) -> bool:
if node is None:
return False
elif node.val == val:
return True
elif val < node.val:
return self._find(node.left, val)
else:
return self._find(node.right, val)
```
对于删除操作,一种常见的策略是将待删除节点的左子树中最大值或右子树中最小值替换为该节点。该实现具体可以参考“剑指Offer第18题:树的子结构”一文。
在运用方面,二分搜索树可以作为多个算法的基础数据结构,如:
- 了解长度固定的数据的平衡方法(即一些排序算法,如快速排序和堆排序)的数据结构
- 得到有序数据的中位数
- 带范围的查询
微信扫一扫,领取最新备考资料