二分搜索树-BST,python实现

为什么要用二分搜索树?

二分搜索树最常用的场景就是查找表的实现,其实可以看成是字典的形式,这样的一对对数据,我们就可以通过键来直接查找到对应的值。进行相应的操作。你可能会想到,这样的key的值,可以直接用数组来存储,但很多时候,键值不一定都是整数,所以这时候实现一个二分搜索树就很明智了。

二分搜索树的优势在哪里呢?
比较一下使用三种方法实现这样一个查找表的时间复杂度

二分搜索树的效率是最高的,而且不仅仅是查找,插入,删除等也是非常高效的,因此,我们可以动态的维护数据,除此之外,还有很多业务上的操作二分查找树也能实现,比如min,max,floor,ceil等。

二分搜索树的定义

二分搜索树也是一颗二叉树,如图所示:

与一般的二叉树不同的是,二分搜索树树具有一下三个性质:

  • 若左子树不为空,则左子树上所有节点的值均小于它的根节点的值
  • 若右子树不为空,则右子树上所有节点的值均大于它的根节点的值
  • 以左右孩子为根的子树依然是二分搜索树
  • 没有键值相等的节点

在讲到堆的时候,我曾说堆是一颗完全的二叉树,但二分搜索树并没有这个限制,如下这样的二叉树也是二分搜索树:

因为不是完全的二叉树,所以我们不能再使用数组来存储相应的结构了,在二分搜索树中我们使用节点来存储相应的结构,主要的结构有:

  • key
  • value
  • parent
  • left:左孩子
  • right:右孩子

二叉搜索树的基本功能

初始化二分搜索树的节点

根据上一节说的二分搜索树的主要特点,我们需要设计一下初始化的函数,方便接下来的插入,删除等操作。

#创建树节点类
class TreeNode(object):
    def __init__(self,key,value,parent = None,left=None, right = None):
    #初始化
        self.key = key
        self.value = value
        self.leftChild = left
        self.rightChild = right
        self.parent = parent

    def hasLeftChild(self):
        return self.leftChild

    def hasRightChild(self):
        return self.rightChild

    def isLeftChild(self):
        return self.parent and self.leftChild == self
    def isRightChild(self):
        return self.parent and self.rightChild == self

    def isRoot(self):
        return not self.parent

    def isLeaf(self):
        return not (self.leftChild and self.rightChild)

插入元素

如图所示:

假如要插入一个元素60,比较一下待插入元素(60)和根节点的元素(41)的大小,如果60>41,则判断一下41这个当前节点是否有右孩子(维护性质),如果有,则把右孩子更新为当前节点,做一个递归的操作;如果没有,直接插入到41这个元素右孩子所在位置。
详见python代码:

class BST(object):

    def __init__(self):
        self.size = 0
        self.root = None
    def __len__(self):
        return self.size
    def length(self):
        return self.size

    def insert(self,key,value):
        if self.root:
            self._insert(key,value,self.root)
        else:
            self.root = TreeNode(key,value)
        self.size += 1
        return self.root

    def _insert(self,key,value,currentNode):
        if key < currentNode.key:
            if currentNode.hasLeftChild():
                self._insert(key,value,currentNode.leftChild)
            else:
                currentNode.leftChild = TreeNode(key,value,parent=currentNode)
        elif key == currentNode.key:
            currentNode.value = value
        else:
            if currentNode.hasRightChild():
                self._insert(key,value,currentNode.rightChild)
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值