C++ 树(部分)

前言:其实这些树原理都很容易说出来,重点在于去实现,以及各个问题的亲为。

我暂时不会直接在本文中给出源代码,而是重点说原理和模拟实现误区。

二叉搜索树:

规则:

1.可以是一个空树。

2.如果左子树不为空,则左子树上所有节点都小于根节点的值。

3.如果右子树不为空,则右子树上所有节点都大于根节点的值。

4.他的左右子树也是搜索二叉树。

5.不会有重复值。

模拟实现突出点:

删除:

如以上搜索二叉树图示,删除节点分三种情况,根节点,有一个根节点的节点,有两个根节点的节点。

删除根节点好说,直接删了就行,重点在于后面两种,先说只有一个的,直接把他的孩子给他的父节点就行。就像”留守儿童“。

两个节点呢,就需要有人接待他的位置,那哪些节点可以胜任呢,首先看他可以的条件,比左边都大,比右边都小,好,到这里结果已经显而易见了,就是左边最大节点和右边最小节点,所以二者皆可。

至于插入和查找,直接按照规则做就可以。

这个树当然会出现以下的状况,今天下五子棋的时候也摆出过此阵,我愿叫他苦茶子阵。

这就是规则不全带来的后果,以下两种就会有增加更多的改进之处。

AVL树:

规则:

1.包含上纵规则(部分)

2.左右子树都是AVL树

3.左右子树的高度差(平衡因子)的绝对值不超过1

这里注意一点就是AVL树不一定有平衡因子,他只是一种实现的方式,有很多实现的方式。

平衡因子就是右子树节点个数减去左子树节点个数,不算子节点的另支,左减右,右减左都可以,具体可以单搜下这个。

查找和删除还是那样,插入的话只需要注意平衡因子和规则了(默认带平衡因子的版本),那么就涉及到这里的坑了。

模拟实现突出点:

旋转:

当插入后,高度的变化破环了规则,那么就需要要有所措施。

先把旋转这个东西画出来,这个就是右单旋,相而也有左单旋,用于调节高度,当然这只是示例。

现在文字说明下这个,第一个左节点做头节点,他的右节点变成前头节点的左节点,头节点变成他左节点的右节点。

当然只有左单旋和右单旋不够用,所以还有左右双旋,代码就不举例了,这里的重点便是这个了(个人认为)。

红黑树:

规则:

1.每个节点不是黑色就是红色。

2.没有一条路径是其他路径的两倍。

3.根节点是黑色。

4.如果一个节点是红色,那他的两个子节点必须是红色。

5.每条路径上的黑色节点是相同的。

模拟实现突出点:

插入:

这里先说下,默认插入节点是红色,因为既然插入一个节点给他颜色的话,就意味着必须违反规则四或者五,相对比下选择插入节点为红色。

情况一

有叔节点并且叔节点为红色:

把新插入节点叫cur,此外还用的到的三个节点,然后进行下图的操作。

把父节点和叔节点变成黑色,祖父节点变成红色,此时祖父节点和他的父节点冲突,把祖父节点当作cur,继续进行上述操作。

最后再把祖父节点变黑就好了。

这样就算插入完成了。

情况二

有叔节点并且叔节点为黑色

比如以上的情况,左下的节点有两个红。

把他的父节点和叔节点全都换成黑色。

再把祖父节点做成插入节点类推,最后头节点还是黑色。

情况三

没有叔节点

首先把父节点变黑。

然后进行左单旋,并且把祖父节点变红。

这样就完事了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值