二叉查找树作为一个基本的数据结构,与二分法的线性查找有相似之处。
二叉查找树:若其左子树存在,则其左子树中每个节点的值都不大于该节点值;
若其右子树存在,则其右子树中每个节点的值都不小于该节点值。
一个二叉查找树的图例如下:
查找
假如该二叉树是一个满二叉树的话,那么共有15个节点,树的高度是4,最多查找4次就可以找到树中任意一个值。可以得到: 15 = 2^4 -1;
归纳为,如果有N个节点的满二叉树的话,查找次数为log2(N+1)次,那么查找复杂度就是log2N。
假如每个二叉树每个节点只有一个子树的话,那么该二叉树相当于线性结构,有N个节点,最多要查询N次才能找到树中任意一个值。查找复杂度就是N。
所以二叉查找树的查找复杂度介于Log2N和N之间。
插入
当一个二叉查找树要插入一个节点的时候,其实和查找的过程类似,查找是遍历二叉树找到相等的值,插入是遍历二叉树找到其父节点,如果子节点有空缺,那么就把值插入,如果已存在就插入失败。
以上图为例:假如要插入一个值为4 的节点。和6比去左边,和3比去右边,和5比去左边,但是5是叶子节点,没有子节点了,所以4的节点要插入在5的左边。 所以插入的复杂度和查询是一致的。
删除
删除稍微麻烦一点:
待删除节点的子节点为0:直接删掉。不影响二叉树的结构定义。
待删除节点的子节点为1:将待删除节点的子节点(不论左右)上移到待删除节点的位置。
待删除节点的子节点为2:找到待删除的节点的左子树的最大值或右子树的最小值。替换掉待删除节点的位置即可。这个画图举例下,原图如下:
搞得极端一点,直接删除根节点。也就是值为50的节点,按照上述删除方式执行,结果有二,如下:
如果是找到待删除的节点的左子树的最大值并替换待删除节点的话,50的左子树的最大值是40,40替换原50的位置,整个二叉树仍然符合二叉查找书的结构规则。
或者是找到待删除的节点的右子树的最小值并替换待删除节点的话,50的右子树的最小值是75,75替换原50的位置,整个二叉树仍然符合二叉查找书的结构规则。