二叉树所有基本操作+ python实现+ 理论随机二叉树运行效率分析(完结)

二叉树大家都很熟悉,这里只是用python手写了一份而已,就在分析的后面
在这之前我们可以讨论一下一个随机构建的二叉树的性能
我们对含有n个元素的二叉树的基本操作基本都可以在O(h)内完成,我们要讨论随即构建的二叉树的期望高度:
在这里插入图片描述表示随即构建的二叉树的高度
在这里插入图片描述表示二叉树的指数高度
在这里插入图片描述表示将二叉树排好序之后树根素所在位置

并且在未排序之前我们的
在这里插入图片描述

对于{1,2,3,4,5.。。。。。n}都是等可能的
如果在这里插入图片描述=i
那么树根元素左边是一颗i-1个元素的随机二叉树,右子树是一个包含n-i个元素的随机二叉树,对于指数高度而言,整个树的指数高度等于左右子树中大的那个的二倍
在这里插入图片描述

因为在这里插入图片描述

对于{1,2,3,4,5.。。。。。n}都是等可能的 我们设置的指示器随机变量在这里插入图片描述
的期望都是1/n
所以有在这里插入图片描述

= 在这里插入图片描述(期望的线性性质)

=在这里插入图片描述(独立性)

=在这里插入图片描述(将1/n带入并将2提出)
<=在这里插入图片描述

并且在i从1到n的时候i-1和n-i只是从大小两个方向上遍历而已
所以我们可得:
在这里插入图片描述

之后我们定义运算:在这里插入图片描述

已知0=在这里插入图片描述=在这里插入图片描述<=在这里插入图片描述=1/4

并且已知1=在这里插入图片描述=在这里插入图片描述<=在这里插入图片描述

并且引入等式:
在这里插入图片描述可由在这里插入图片描述反复替换求出

根据上面的0和1我们进行归纳假设:
在这里插入图片描述(根据归纳假设)

=在这里插入图片描述(由上面的引入等式推得)

=在这里插入图片描述
并且根据jensen不等式:
E[f(g(X))]≥f(E[g(X)])
所以
在这里插入图片描述并且对左右两边同时取对数
在这里插入图片描述

class Node(object):
    def __init__(self, key=None, left=None, right=None, p=None):
        self.key = key
        self.left = left
        self.right = right
        self.p = p

class Tree(object):
    def __init__(self):
        self.root = None
    pass


class BinaryTreeService(object):
    def __init__(self):
        pass

    def insert(self, T, z):
        y = None
        x = T.root
        while x:
            y = x                   # y作为parent
            if z.key < x.key:       # 不断下移x直到变成None
                x = x.left
            else:
                x = x.right
        z.p = y                     # 设置插入点的parent
        if y == None:               # 存在原来是空树的情况所以进行判断
            T.root = z
        elif z.key<y.key:           # 再次判断大小并且赋值
            y.left = z
        else:
            y.right = z
        return T
    def treeMininum(self,x):
        while x.left:
            x = x.left
        return x

    # 定义transplant用来用另一棵子树代替一棵子树并成为其双亲的孩子结点
    # 现在我们用以v为根的子树替换一颗以u为根的子树
    def transplant(self, T,u,v):
        # 如果 u是T的根
        if u.p == None:
            T.root = v
        elif u == u.p.left:
            u.p.left = v
        else:
            u.p.right = v
        if v:                   # 一定注意插入的可能是空的情况,空没有父节点,如果不是空那么给新的子树v的parent赋值
            v.p = u.p
        return T
    # 在删除之前我们要明白,删除分成三种情况
    # 如果删除的结点z没有孩子结点,那么简单删除并 修改父节点
    # 如果z只有一个孩子,那么直接提升这个孩子到z的位置,修改父节点
    # 如果z有两个孩子那么找z的后继y一定是z的左子树,并让y占据z的位置,z的左子树会成为y的最后继的左子树。
    def treeDelete(self, T, z):
        bts = BinaryTreeService()
        if z.left == None:
            bts.transplant(T, z,z.right)
        elif z.right == None:
            bts.transplant(T, z,z.left)
        else:
            y = bts.treeMininum(z.right)
            if y.p!=z:
                bts.transplant(T,y,y.right)
                y.right = z.right
                y.right.p = y
            bts.transplant(T,z,y)
            y.left = z.left
            y.left.p = y
        return T
        pass

    # 查找关键字结点,需要传入x:指向根节点的指针, 关键字:k
    def treeSearch(self, x, k):
        bts = BinaryTreeService()
        if x==None or k == x.key:
            return x
        if k<x.key:
            return bts.treeSearch(x.left,k)
        else:
            return bts.treeSearch(x.right,k)

    # 还有第二种
    def iterativeTreeSearch(self,x,k):
        while x!= None and k!=x.key:
            if k<x.key:
                x = x.left
            else:
                x = x.right
        return x
        pass

    # 查找后继
    def treeSuccessor(self,x):
        bts = BinaryTreeService()
        # 如果由右子树。那么返回右子树的最小值
        if  x.right !=None:
            return bts.treeMininum(x.right)
        y = x.p
        # 这里是第二种情况,没有就要沿着右子树向上一直到当前子树不是其父节点的右子树。。。。这个父节点就是我们要的元素的后继
        while y and x==y.right:
            x= y
            y = y.p
        return y

    # 中序遍历二叉树:x:根的指针
    def treeWalk(self,x):
        bts = BinaryTreeService()
        if x:
            bts.treeWalk(x.left)
            print(x.key)
            bts.treeWalk(x.right)
        pass


if __name__ == '__main__':
    T = Tree()
    bts = BinaryTreeService()

    keys = [6,5,2,7,10,8,9,1,65,3]
    for currentKey in keys:
        z = Node(key=currentKey)
        T = bts.insert(T, z)
    print('中序遍历结果是:')
    bts.treeWalk(T.root)

    print('后续测试:')
    print(bts.treeSuccessor(T.root.right.right.left).key)
    print('查找关键字结点测试')
    print('treeSearch:', bts.treeSearch(T.root,10).key)
    print('treeSearch:', bts.iterativeTreeSearch(T.root, 10).key)

    print('删除测试')
    print('treeDelete', bts.treeDelete(T, bts.treeSearch(T.root,10)))
    print('删除之后的中序遍历结果是:')
    bts.treeWalk(T.root)
    



证明正确性附加了运行结果:


中序遍历结果是:
1
2
3
5
6
7
8
9
10
65
后续测试:
9
查找关键字结点测试
treeSearch: 10
treeSearch: 10
删除测试
treeDelete <__main__.Tree object at 0x00000212FCF84128>
删除之后的中序遍历结果是:
1
2
3
5
6
7
8
9
65

Process finished with exit code 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值