专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

Binary Search Trees(BST)

BST的性质

BST的形状为

93_1.png

  • 每个BST中的节点x,存在一个key,一个指向父节点的parent指针,同时还有一个左子树和右子树

root的parent不存在

  • 左子树值y与父节点x满足 key(y) <= key(x),右子树z满足 key(x) <=key(z)

插入实现机制

假设元素的插入顺序为30,40,17,20,14 刚开始的时候没有元素,插入新的元素

93_2.png然后插入第二个元素40,它比30要大,置为它的右节点

93_3.png插入第三个元素17,比30要小,置为它的左节点

93_4.png然后是20,比30小,找到做子树,左子树的节点值为17,再次比较

93_5.png最后一次元素再次插入,得到最终的BST结构

93_6.png

def insert(self,z):
    x = self.root
    y=None # x's parent
    while x!=None :
        //找到要插入的位置
        y=x
        if x.key <= z.key:
            x=x.right
        else:
            x=x.left
    if y == None:
    //新插入的元素为第一个节点
        self.root = z
        z.parent = None
    else:
    //接入新的节点
        z.parent = y
        if y.key <= z.key:
            y.right = z
        else:
            y.left = z

它的耗时为O(lgn)

找到后继节点

后继节点即从值上来讲,找到比要找的元素要大最接近的值,根据BST的性质,它肯定在右子树上,所以如果存在存在右子树,就是右子树上的最小值,否则回溯到父节点,直到父节点不存在,或者遇到第一个不存在右节点关系的父子节点即得到后继值

17的后继是20,即17的右子树的节点;

20的后继是30,由于20没有右子树,会先回溯到17,然后17是它的父节点的左子树,那么它就是后继节点;

40的后继不存在;

def successor(self,node):
    if node == None:
        return None
    if node.right != None:
        # 后继一定在node的右节点
        return self.minimum(node.right)
    y = node.parent
    # 后继节点只能在右节点
    while  y!=None and node == y.right:
        node = y
        y=y.parent
    return y

最小值则一直递归到左子树没有节点即可

def minimum(self,node=None):
    x = self.root if node == None else node
    while x!=None and x.left!=None:
        x = x.left
    return x

删除节点

节点删除之后,必须要维持原有的BST性质

93_7.png

  • 删除节点13,它一个子节点都没有,直接删除即可

93_8.png

  • 删除节点16,只有右节点,直接有右节点替代即可

93_9.png

  • 删除5,它既有左子树又有右子树,需要找到后继补上

93_10.png

def delete(self,node):
    if node.left == None:
        # 如果node.right 是None 相当于把要删的节点直接置成None,否则 后继者一定是第一个right值
        return self.transplant(node,node.right)
    elif node.right == None:
        # node.left 一定存在,只需要替换节点之间的指针
        return self.transplant(node,node.left)
    else:
        # 左子树和右子树都有,要维持BST的性质,必须找到后继节点
        successor = self.minimum(node.right)
        if successor != node.right:
            # 最小的左边的值一定不存在
            self.transplant(successor,successor.right)
            # right有变化
            successor.right = node.right
            # 修改原来节点的父节点 node.right 一定存在
            successor.right.parent = successor 
        self.transplant(node,successor)
        successor.left=node.left
        # 修改原子节点的父节点 node.left一定存在
        successor.left.parent = successor
        return node

指针变换关系为

def transplant(self,d,r):
    """ d been delete r replecement"""
    if d.parent == None:
        self.root = r
    elif d == d.parent.left:
        d.parent.left = r
    else:
        d.parent.right = r
    if r!=None:
        r.parent = d.parent
    return d

代码详情

文章永久链接:https://tech.souyunku.com/47215

未经允许不得转载:搜云库技术团队 » Binary Search Trees(BST)

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们