二叉排序树(BST):任何结点满足左子树<根结点<右子树。
中序遍历可以获得递增序列。
查找操作:比结点小,往左子树走,等于说明找到了,就是这个结点,比结点大往右子树走。如果不含有左子树或右子树,说明查找失败。
添加操作:先完成查操作,一般来说二叉排序树每一个结点索引值不相同,相同报错,所以查找返回为空的时候,为NULL指针,同时该指针的位置即为需要插入的点。
删除操作:删除操作比较麻烦需要分情况讨论
- 如果是叶子结点,直接删除
- 如果含有单个的左子树,或者右子树,将子树提上来即可
- 如果含有两个子树,可以找到该结点的前驱或者后继,将其替换原本需要删除点,然后删除其所在结点
查找次数与树的高度息息相关,如果树比较高,查找可能需要比较多次,最极端情况即为都是左子树或者右子树,就等价于线性表的顺序查找。
所以需要保证树的高度在一个合理范围,就能保证查找效率。
平衡二叉树(AVL)
如果能够保证左子树与右子树高度差值在1之内,就能够保证查找效率在O(logn)。将这种树称为平衡二叉树。
平衡二叉树所有操作与二叉查找树相同,只是在进行插入与删除时候,可能会导致平衡性被破坏,所以需要根据结果来进行平衡操作。
插入操作导致的不平衡:需要从插入点向根结点进行走,寻找到第一个不平衡子树,对他进行平衡修正。
可以进行讨论验证,插入点与最小不平衡子树根结点位置情况只会出现四种情况:
根结点的第一个字母子树的第二个字母子树上。
- LL:需要进行右单旋
- RR:需要进行左单旋
- LR:需要先进行左单旋,再进行右单旋
- RL:需要先进行右单旋,再左单旋
LL,RR都是将父结点换到根结点,LR,RL则是将孙结点换到了根结点。
能够保证修改最小不平衡子树就能够保证整个树是平衡二叉树是因为,在插入结点之后,使得树的高度+1,但在这四种情况之下,都是树高从h+1变为了h,树的高度-1,到根结点都会-1,所以树就平衡了。
在删除情况后可能也要进行平衡操作,但是与插入平衡有一些不同:
- 进行排序二叉树相同删除操作
- 从真正删除的结点而不是替换结点向根结点寻找有没有最小不平衡子树
- 如果有,找出个子最高的儿子与个子最高的孙子,他们构成四种可能性与上面LL,RR,LR,RL相同,操作也相同
- 完成旋转操作,子树平衡了,但是还要继续向根结点看,因为这里的平衡可能向上传导,如果有不平衡,循环3,4
为什么可能向上传导,因为在删除结点之后进行四种旋转操作可能导致最小不平衡子树的高度减少,所以可能向上传导。