红黑树的原理及实现(TypeScript)

         前言:找博客学习红黑树,发现有些比较晦涩难懂,有些讲的不清不楚。幸运地在B站找到一部视频,按照算法导论讲的例子,听懂了。所以好的教材挺重要的。
        然后决定自己写一篇博客讲解一下我的理解和实现,希望能帮助到有需要的小伙伴。
        视频链接:1小时搞定红黑树_哔哩哔哩_bilibili,感兴趣的可以去看看

        抱歉,写完之后发现图里的树画得不严谨,不完整,看上去不是平衡的,但是我也懒得改了。请大家主要考虑情况和解决方案即可。可自行画一个完整的红黑树,再按照解决方案进行操作、思考。

二叉搜索树

        首先了解一下二叉搜索树,它的规则就是父节点的左子树上的点都要比它“小”,右子树上的右子树上的点都要比它“大”。左右顺序不重要,重要的是要有这个顺序,让它是一颗有序的二叉树。当它有序的时候且是一个完全平衡的时候(即除了最后一层,其它层都是满的,没有空节点),它的搜索效率是最高的。类似于二分搜索,时间复杂度是O(logN)。

        查找:类似于二分法,比如要找5,则7-->3-->5。找到返回。

        插入:找到合适的位置,再插入。比如插入10,则 7-->9-->13,比13小,插入左子节点。

        删除:
                如果目标节点没有子节点如1,则直接删除即可。
                如果目标节点有1个子节点如13,则删除13,将节点10顶替上去。 
                如果目标节点有2个子节点,则取其中序遍历的前驱节点或后继节点作为实际删除节点,先交换值,再进行删除操作。如节点9,其中序遍历的后继节点为10,则两节点交换值,再进行删除操作。

        

        修改:即先做删除,再做插入操作。

        至此,二叉搜索树的四种操作讲解完毕,它们的处理都是为了保证二叉搜索树的有序性。

 

左旋和右旋

        再了解一下二叉搜索树的左旋和右旋。

        左旋:
                以目标节点为支点进行向左的旋转。
                条件是目标节点不为空,且右子节点不为空。如下图是以节点a为支点进行左旋。

        右旋:
                以目标节点为支点进行向右的旋转。
                条件是目标节点不为空,且右子节点不为空。如下图是以节点b为支点进行旋转。

         

 

        左旋和右旋是一个对称的操作, 过程比较简单,我也就不做赘述了,相信大家看一看就能理解,这2步的操作,也保证了二叉搜索树的有序性。

红黑树

        基础讲完现在进入红黑树的内容,红黑树也是一颗二叉搜索树。
        二叉搜索树越接近完全平衡,则其查找效率越高。当你进行了删除或插入操作的时候,会破坏平衡,此时则需要进行调整平衡的操作。当然可以通过一系列操作重新调整为完全平衡,但是操作会很繁琐,在频繁插入和删除的时候代价过大。
        红黑树则利用颜色来限制自身的高度,来实现了一种近乎平衡。
        颜色条件:
                1、节点有颜色,红色或者黑色。
                2、根节点必须为黑色,空节点视为黑色。
                3、红色节点不能相连。
                4、以任意节点为起点,到它的叶子节点上的黑色数目要相等。

        从根节点出发,到叶子节点的黑色节点数目为N,则其高度不会超过2N。

        下面来讲红黑树是如果调整颜色的平衡,关注插入和删除即可。查找不改变节点,修改则是先删除后插入。
        颜色平衡的主要思想是要么向上推进,因为到根节点一定能解决,要么就是往可解决的状态进行调整。理解这句话,则可以理解后续的所有操作,后续的操作基本是递归处理。

插入操作

        插入操作首先按照二叉搜索树的规则,进行插入。然后再进行调整,使颜色平衡。
        
        插入的节点为红色,然后根据以下几种情况分别处理,下面的()里会说明一些确定的信息。
                1、根节点为空,则插入的节点作为根节点,设为黑色即可。
                2、父节点为黑色,直接平衡,无需处理。
                3、父节点为红色(此时祖父节点必为黑色)。
                        3.1 叔节点为红色。
                        3.2 叔节点为黑色,插入节点与父节点不同侧,不同侧指父节点是祖父节点的左(右)节点,而插入节点是父节点的右(左)节点。后文不再做赘述。
                        3.3 叔节点为黑色,插入节点与父节点同侧。

        情况1、2很简单,跳过。然后来讲情况3中的具体处理。

        3.1 父节

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值