Python实现二叉搜索树-查找树-排序树【通俗易懂】

二叉搜索树定义

父亲节点的左孩纸小于父亲节点,右孩纸大于父亲节点

从别人博客拉了一张图

在这里插入图片描述

复杂度分析

1、查询时间复杂度为 O(log2 n)~O(n)。
时间复杂度和二分法类似,因为二叉树就是用到了二分的思想

最坏情况会退化成一条链
在这里插入图片描述
这时的复杂度为O(n)




代码实现


1、初始化类
用python的列表来实现树形结构 方便点 size为树的元素大小
传入size要可能大,因为用数组来模仿树形结构有很多空的元素,数组模仿出来的是一颗满二叉树
比如0的节点孩纸为1 2
1 —>3 4
2 —>5 6
0 1 2 3 4 5 6 7 8 是按层来遍历树的

所以如果父亲节点的位置为n 则左孩纸为n*2+1

右孩纸就在左孩纸边上n*2+2

    def __init__(self,size):
        self.tree=[None]*size    #没有元素的都为None

    def __len__(self):
        return len(self.tree)

    def __str__(self):
        return str(self.tree)

2、插入元素

    def insert(self,v,root=0):
        if self.tree[root]==None:
            self.tree[root] = v
        elif v>self.tree[root]:  #大于父亲就插入到父亲的右树 反之左
            self.insert(v,root*2+2)  
        else:
            self.insert(v,root*2+1)

3、判断元素是否存在【二分查询】

    def isExist(self,v,root=0):   #目标元素大于父亲 往右边找 小于父亲往左边找
        while self.tree[root]!=None:   
            if self.tree[root]==v:  
                return True
            if self.tree[root]>v:  
                root=root*2+1
            else:
                root = root*2+2
        return False

4、查找最小值【就是查找最左边的元素】
这个操作主要是用于删除元素用
属于内置操作

    def _findMin(self,root=0):  #找最左边的
        if self.tree[root*2+1]==None:
            return root
        return self._findMin(root*2+1)

5、删除操作【最复杂】

分三种情况考虑

1、待删除的节点无孩纸节点:直接删除即可

2、待删除的节点有两个孩纸节点:需要和当前节点右子树中最小的节点互换位置再删除,因为待删除节点右树最小的节点就是最接近当前节点的点,这样巧合满足二叉树的规则

3、待删除节点仅仅有一个孩纸:
将这个节点与那个孩纸互换再讲删除的节点转移到孩纸节点,进行下沉
【因为万一孩纸节点下面还有树的话就要进行递归删除了】

建议自己画一画试一试

    def delete(self,x,root=0):  #x代表删除的元素值
        if x<self.tree[root]:  #在左边
            self.delete(x,root*2+1)
        elif x>self.tree[root]:
            self.delete(x,root*2+2)

        else:
            if self.tree[root*2+1]!=None and self.tree[root*2+2]!=None: #左右孩子都不为空
                m = self._findMin(root*2+2)  #寻找右边最小的
                self.tree[root],self.tree[m] = self.tree[m],self.tree[root]
                self.delete(x,root*2+2)
            elif self.tree[root*2+1]==None and self.tree[root*2+2]==None:
                self.tree[root] = None
            else:
                if self.tree[root*2+1]==None:  #左边为空 和右边节点换位置
                    # print(self.tree[(root*2+2)*2+1])
                    m = self._findMin(root*2+2)
                    self.tree[root],self.tree[m] = self.tree[m],self.tree[root]
                    self.delete(x,m)
                else:  #右边为空
                    m = self._findMin(root * 2 + 1)
                    self.tree[root], self.tree[m] = self.tree[m], self.tree[root]
                    self.delete(x,m)

6、中序遍历【这样巧好是升序排列】

右–>中---->左
在这里插入图片描述
这颗树的中序遍历结果为
ACBDFHEMG

    def Order(self,root=0):
        if self.tree[root]==None:
            return
        self.Order(root*2+1)
        print(self.tree[root])
        self.Order(root*2+2)

7、测试样例

tree = searchTree(100)

tree.insert(2)
tree.insert(5)
tree.insert(1)
tree.insert(20)
tree.insert(9)
tree.insert(10)
tree.Order()
print("====")
tree.delete(5)
tree.delete(2)
tree.Order()
1
2
5
9
10
20
====
1
9
10
20

8、完整代码

class searchTree():
    def __init__(self,size):
        self.tree=[None]*size

    def __len__(self):
        return len(self.tree)

    def __str__(self):
        return str(self.tree)


    def _findMin(self,root=0):  #找最左边的
        if self.tree[root*2+1]==None:
            return root
        return self._findMin(root*2+1)

    def insert(self,v,root=0):
        if self.tree[root]==None:
            self.tree[root] = v
        elif v>self.tree[root]:
            self.insert(v,root*2+2)
        else:
            self.insert(v,root*2+1)

    def delete(self,x,root=0):
        if x<self.tree[root]:  #在左边
            self.delete(x,root*2+1)
        elif x>self.tree[root]:
            self.delete(x,root*2+2)

        else:
            if self.tree[root*2+1]!=None and self.tree[root*2+2]!=None: #左右孩子都不为空
                m = self._findMin(root*2+2)  #寻找右边最小的
                self.tree[root],self.tree[m] = self.tree[m],self.tree[root]
                self.delete(x,root*2+2)
            elif self.tree[root*2+1]==None and self.tree[root*2+2]==None:
                self.tree[root] = None
            else:
                if self.tree[root*2+1]==None:  #左边为空 和右边节点换位置
                    # print(self.tree[(root*2+2)*2+1])
                    m = self._findMin(root*2+2)
                    self.tree[root],self.tree[m] = self.tree[m],self.tree[root]
                    self.delete(x,m)
                else:  #右边为空
                    m = self._findMin(root * 2 + 1)
                    self.tree[root], self.tree[m] = self.tree[m], self.tree[root]
                    self.delete(x,m)

    def isExist(self,v,root=0):
        while self.tree[root]!=None:
            if self.tree[root]==v:
                return True
            if self.tree[root]>v:
                root=root*2+1
            else:
                root = root*2+2
        return False

    def Order(self,root=0):
        if self.tree[root]==None:
            return
        self.Order(root*2+1)
        print(self.tree[root])
        self.Order(root*2+2)

tree = searchTree(100)

tree.insert(2)
tree.insert(5)
tree.insert(1)
tree.insert(20)
tree.insert(9)
tree.insert(10)
tree.Order()
print("====")
tree.delete(5)
tree.delete(2)
tree.Order()
# tree.tree





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值