二叉查找树的重要特点是:左子树一定不大于父结点,右子树一定比父结点大,所以可以将搜索时间复杂度控制在 log n 的水平上。
定义结点:
class TreeNode<E> { E element; TreeNode<E> left; TreeNode<E> right; public TreeNode(E e) { element = e; } }
参考 BST 的重要特点,依照大小的模式寻找:
若待搜索元素小于结点,搜索左子树;
若待搜索元素大于结点,搜索右子树;
若待搜索元素等于结点,返回true;
在 BST 中插入一个元素,关键在于确定在树中插入元素的位置,思路是确定新结点的父结点所在的位置。可以借助 2 中查找 BST 的方式找到插入位置。
BST 的遍历是很重要的操作,主要应用的就是迭代方法。以下是五种常用的遍历模式。
先遍历左子树,接下来是父结点,然后是右子树。特点是 以递增顺序显示一个 BST 中所有结点。
先遍历父结点,接下来是左子树,最后是右子树。典型应用是打印结构文档。
先遍历左子树,接下来右子树,最后是父结点。典型应用是找出目录中文档的个数,在找出根目录的大小之前得到每个子目录的大小。
为了从一个 BST 中删除一个元素,我们需要定位该元素所在位置和它的父结点位置。假设 current 指向二叉查找树中包含该元素的结点,而 parent 指向 current 结点的父结点。 current 结点可能是 parent 结点的左孩子,也可能是右孩子。这里需要考虑下面两种情况:
1. 若 current 结点没有左孩子,这时需要将该结点的父结点和当前结点的右孩子相连。
2. 若 current 结点有一个左孩子,那么假设 rightMost 指向 current 左子树中的最大元素,该元素的父结点是 parentOfRightMost ,那么我们要做的就是用 rightMost 元素替换 current 元素,将 parentOfRightMost 与 rightMost 的左子树相连。
利用之前的各种遍历模式+java.util.Iterator 接口,我们可以定义自己的迭代器,注意,java.util.Iterator 接口定义了三个函数:
1. +hasNext(): boolean
2. +next(): Object
3. +remove(): void