红黑树

前置知识:

1, BST(二叉搜索树)

定义:BST的中序遍历序列是一串单调序列,一般是升序序列

插入值e:顺着树向下查找,直到null,创建值为e的节点替代null

删除值e:查找到e,然后选择直接后继,先右然后左到底(升序),易证该节点为直接后继。找到直接后继之后,将e与直接后继交换位置,再删除e。

直接后继节点的特征:没有左孩子。

2,AVL树(平衡二叉树)

定义:在二叉搜索树的前提下满足如下条件,设仅一个节点的树高度为0,路径上每有一条边,高度加1。某节点高度等于该节点最长路径的边数;平衡条件,左右子树高度之差小于等于1,即h左-h右可以为 1,0,-1;

查找:

顺着树向下,很容易。

插入算法:

第一步:利用BST的搜索算法搜索到插入位置——必为某个叶节点的左右孩子:NULL(既然可以插入,必然搜索失败,而失败的查找指针必然落到叶节点的左右孩子:NULL上)

第二步:寻找三个节点x,y,z的位置关系。如何确定x,y,z?首先要知道,插入某个节点e可能会改变哪些节点的高度——答案是从e到根节点这条路径上L的所有节点的高度。首先确定x,x为路径L上,从e开始逆向到根节点的第一个因为插入e导致高度不平衡的节点;其次确定y,对比x的左右孩子,更高的设置为y;最后确定z,对比y的左右孩子,更高的设置为z(若高度相同,取左还是右取决于y为左孩子还是右孩子)。确定好x,y,z后,来判断他们的位置关系。关系A:顺着x到z的路径画线,路径不转弯(情况m:y为x的左孩子,z为y的左孩子;情况n:y为x的右孩子,z为y的右孩子) 关系B:路径转弯。

第三步:对于关系A:在x,y之间做一次左顺右逆旋转。对于关系B,依照情况在y,z之间做一次旋转,将其转化为关系A,再做左顺右逆旋转。

左顺右逆旋转:情况m做顺时针,情况n做逆时针。说白了就是将一个三个节点构成的斜坡转换为一个波浪的形状。这样可以恢复平衡。

删除算法:

找x,y,z节点的方法与插入算法一致。旋转也大同小异,不过注意存在失衡传播:照片不拍了很麻烦,参见邓俊辉数据结构——AVL树。

3,B-树

存在理由:为了减少io操作的次数,将多个节点合并为一个大节点,就高度而言,b树所有节点左右子树高度相同。

定义:先取向上取整符号为↑,向下取整符号为↓。设最大分支数m。

a:B树最大分支数为m,最小分支数为↑m/2。(关键码数等于分支数减一)根节点除外,根节点分支数>=2,<=↑m/2;

b:B树所有叶节点具有相同的深度。

节点的数据结构:由两组序列,即关键码序列和分支序列构成。

插入操作:

先搜索到应该插入的大节点,再利用向量的search操作找到插入位置。必然是在最底部的大节点中插入。

成功插入后可能会遇到上溢的情况:分支数大于m

处理上溢:

选取↓m/2作为分割点,将关键码分为左右两部分,将↓m/2处的点提升至父节点。

删除操作:

与BST类似,应该先替换,再删除。

成功删除后可能会遇到下溢情况:分支数小于↑m/2

两种解决办法:

1,兄弟节点B有多余:设下溢节点为A,向兄弟节点B借出一个关键码到父节点,父节点该处的关键码下移到A节点相应位置。

2,兄弟节点B没有多余:向父节点借出一个关键码,将A,B粘接起来。

 

红黑树:

10号前更新

转载于:https://my.oschina.net/u/3400107/blog/3103161

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值