二叉树大家都很熟悉,这里只是用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