Java基础知识总结(20)

二叉查找树

二叉查找树的节点有一个元素X和两个指针域,左指针指向小于X的元素,右指针指向大于X的元素。

假设我们的插入序列是1~10,那么这颗树会演变成只有右链接的形式,树高会增加到10层,这个时候已经不具备O(LogN)的查找时间复杂度,因为这颗树退化成了链表。

因此对二叉树进行平衡调整是很重要的一个环节,无论是AVL还是红黑树,它们本质上都是希望尽可能保证这颗二叉查找树中的元素尽量均衡的分布在树的两侧。

当我们向一颗二叉查找树中插入一个元素Y的时候,我们会一直与树中的节点进行大小比较,如果Y小于当前元素,就往左走,如果Y大于当前元素,就往右走,直到达到叶子节点,这个时候我们可以把Y插入这颗二叉查找树了。

由于这次的插入动作,整棵树可能会发生一些不平衡,因此我们需要在插入后进行一次平衡调整,使得整棵树恢复到平衡的状态(具体如何调整,要看树是AVL还是红黑树亦或是其他的平衡树)。

二叉查找树的删除是一个很有意思的问题,不同于插入的是,待删除的元素并不能保证一定出现在树中的叶子节点。这将带来一个棘手的情景,即我们需要从树的中间部分取走一个元素,而且在取走后还需要经过调整来使得整颗树满足平衡的性质。从树的中间部分直接取走一个节点的场景实在是太多,也牵扯到了太多相关的节点,这种操作很难实现。

好在有人提出了一个观点,我们对查找树中一个节点的删除,其实可以不必真的改动这个节点的位置。由于查找树的特殊性质,将某个元素节点删除后,它有两个最佳替代者,分别是有序序列中的前驱元素和后继元素。

我们还是以一个包含元素1~10的二叉查找树为例,如果我们希望删除5所在的节点,那么让4或者6替代它的位置都是可行的。作为前驱元素的4,会存放在5所在节点的左子树的最右侧;作为后继元素的6,会存放在5所在节点的右子树的最左侧。

关于这个结论,大家只需稍加思索便可以明白。

现在我们又让问题简化了,也就是说,删除某个节点的时候,我们先找到它的前驱元素或者后继元素(随便选一个),将它的前驱元素直接填到待删除的节点,然后再把它的前驱元素或者后继元素删除。

这个时候问题就转化成了在二叉查找树中删除一个没有左子树的节点(或者是一个没有右子树的节点),我们只需要将这个节点删除再进行对应的平衡调整即可(虽然还是需要调平,但是比直接在树中层删除一个同时具备左右儿子的节点要容易很多)。

注意,此处并没有强调是针对红黑树的操作,因为红黑树和AVL都是二叉查找树,它们都适用这个方法。

相关推荐
nice_lcj5201 小时前
LRU 缓存入门:它是什么、怎么用、面试怎么手写
java·数据结构·缓存·面试·lru
꧁细听勿语情꧂2 小时前
直接选择排序,堆排序,冒泡排序,递归快速排序、hoare版本、挖坑法、lomuto前后指针,非递归快速排序
c语言·开发语言·数据结构·算法
Pniubi15 小时前
关于算法用现成数据结构和手撕
数据结构
老师我太想进步了20261 天前
【数据结构-6】算法美学之单链表(1)
数据结构·算法
希望我万事顺遂1 天前
力扣hot100-滑动窗口最大值
数据结构·算法·leetcode
꧁细听勿语情꧂1 天前
二叉树余题,排序、直接插入排序、希尔排序
c语言·开发语言·数据结构·算法
是main不是漫1 天前
【双指针|LeetCode1089 复写零】巧用逆向思路,破解原地覆盖陷阱
数据结构·算法·leetcode
饮水桶_T2 天前
JAVA IO流笔记
开发语言·数据结构·算法
wo_jack2 天前
C++ 入门笔记(十七):list 入门 —— 为什么 list 不能 sort?
数据结构·c++·面试·stl·list
zaizai10072 天前
算法(左程云)1
数据结构