二叉查找树(Binary Search Tree)的python实现及算法分析

二叉查找树(BST)

特点:比父节点小的key都出现在左子树,比父节点大的key都出现在右子树。
在这里插入图片描述

二叉查找树的python实现
class BinarySearchTree(object):   
    def __init__(self, key):    ##初始化
        self.key = key
        self.left = None
        self.right = None

    def find(self, x):   
        if x == self.key:
            return True
        elif x < self.key and self.left:  # 如果x小,则去左子树找
            return self.left.find(x)
        elif x > self.key and self.right:  # 如果x大,则去右子树找
            return self.right.find(x)
        else:
            return None  # 找不到返回None

    def findMin(self):
        if self.left:  # 如果左节点存在,最小值一定在左节点的最深处
            return self.left.findMin()
        else:
            return self.key  # 如果左节点没有,那么根节点最小

    def findMax(self):
        if self.right:  # 如果右节点存在,最大值一定在右节点的最深处
            return self.right.findMax()
        else:
            return self.key  # 如果右节点没有,那么根节点最大

    def insert(self, x):
        if self.find(x):  # 如果找到了该节点,则什么也不做
            return None
        else:  # 如果没有找到则开始插入
            if x < self.key:  # 如果插入值小,则插入左子树
                if self.left:  # 先判断左子树是否存在
                    return self.left.insert(x)
                else:
                    newTree = BinarySearchTree(x)
                    self.left = newTree  # 如果左子树不存在,则把该节点设为左子树
            elif x > self.key:  # 如果插入值大,则插入右子树
                if self.right:
                    return self.right.insert(x)
                else:
                    newTree = BinarySearchTree(x)
                    self.right = newTree

    def delete(self, x):
        if self.find(x):  # 首先判断该节点是否存在
            if x < self.key:  # 如果要删的数据比该数据self.key小,从左子树删起
                self.left = self.left.delete(x)
                return self
            elif x > self.key:  # 如果要删的数据比self.key大,从右子树删起
                self.right = self.right.delete(x)
                return self
            else:  # 如果就是该数据,判断他是否有左右子树
                if self.left and self.right:  # 如果左右子树都存在
                    minkey = self.right.findMin().key  # 把右子树中最小的点连接原来x的父节点, 并且右子树中删除该点
                    self.key = minkey
                    self.right = self.right.delete(minkey)
                    return self
                else:  # 如果左右节点不全存在
                    if self.left:
                        return self.left
                    else:
                        return self.right
        else:
            return self


bst = BinarySearchTree(17)
node_list = [17, 5, 29, 38, 35, 2, 9, 8, 16, 11]
for l in node_list:
    bst.insert(l)
print(bst.findMax())
print(bst.findMin())
print(bst.find(10))
print(bst.delete(11))

算法分析:

(1)二叉查找树的性能决定因素在于二叉搜索树的高度(最大层次),而高度又受数据项key插入顺序的影响。
(2)若key的列表是随机分布的话,那么两侧的键值大致相等
(3)BST的高度就是log2 n,n是节点的个数,而且该树是平衡树

平衡二叉查找树(AVL树)

特点:能够在key插入是一直保持平衡的二叉查找树。
在AVL实现中,需要对每个节点跟踪“平衡因子”参数,其定义为左右子树的高度差。AVL树的平衡因子都在-1,0,1之间,
AVL树的python实现
1.AVL树的实现,遍历与查找操作与二叉查找树相同。
见上面
2.AVL树的插入操作
插入一个节点可能会破坏AVL树的平衡,可以通过旋转操作来进行修正。插入一个节点后,只有从插入节点到根节点的路径上的节点的平衡可能被改变。

def put(self,key):
        if not self.root:
            self.root=Node(key)
        else:
            self.root=self._put(key,self.root)
    def _put(self,key,node):
        if node is None:
            node=Node(key)
        elif key<node.key:
            node.left=self._put(key,node.left)
            if (self.height(node.left)-self.height(node.right))==2:
                if key<node.left.key:
                    node=self.singleLeftRotate(node)
                else:
                    node=self.doubleLeftRotate(node)
            
        elif key>node.key:
            node.right=self._put(key,node.right)
            if (self.height(node.right)-self.height(node.left))==2:
                if key<node.right.key:
                    node=self.doubleRightRotate(node)
                else:
                    node=self.singleRightRotate(node)
        
        node.height=max(self.height(node.right),self.height(node.left))+1
        return node

算法分析:经过复杂的put方法,AVL树始终能维持平衡,get也始终保持O(log n)的高性能。
AVL树的put方法的时间复杂度还是O((log n)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨猪起飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值