classBinaryTree(object):def__init__(self, data):
self.data = data
self.child_l =None
self.child_r =None
self.parent =None# 创建
a = BinaryTree(1)
b = BinaryTree(2)
c = BinaryTree(3)
d = BinaryTree(4)
e = BinaryTree(5)
f = BinaryTree(6)
g = BinaryTree(7)# 构造节点关系
a.child_l = b
a.child_r = c
b.child_l = d
b.child_r = e
c.child_l = f
c.child_r = g
b.parent = a
c.parent = a
d.parent = b
e.parent = b
f.parent = c
g.parent = c
# 设置根
root = a
print('根:', root.data)
'''
中序遍历后继节点
左中右
当前节点有右孩子:返回右孩子的最左节点
当前节点没有右孩子:
当前节点是父节点的左孩子,返回父节点;
当前节点是父节点的右孩子,向上找,直到某一结点是其父节点的左孩子,返回父节点
'''deffind(node):if node ==None:returnNoneif node.child_r !=None:
tmp = node.child_r
while tmp and tmp.child_l:
tmp = tmp.child_l
return tmp
else:
p = node.parent
while p and p.child_l != p:
node = p
p = p.parent
return p
print(find(a).data)
'''
中序遍历前继节点
左中右
当前节点有左孩子:返回右孩子的最右节点
当前节点没有左孩子:
当前节点是父节点的右孩子,返回父节点;
当前节点是父节点的左孩子,向上找,直到某一结点是其父节点的右孩子,返回父节点
'''deffind1(node):if node ==None:returnNoneif node.child_l !=None:
tmp = node.child_l
while tmp and tmp.child_r:
tmp = tmp.child_r
return tmp
else:
p = node.parent
while p and p.child_r != p:
node = p
p = p.parent
return p
print(find1(a).data)
3、二叉树的序列化和反序列化(前序、层序)
'''
序列化:用文件记录树结构,可以永久保存
'''# 先序序列化defstring(root):
res =[]defpre(root):if root ==None:
res.append('#')else:
res.append(str(root.data))
pre(root.child_l)
pre(root.child_r)
pre(root)return' '.join(res)print('序列化结果:', string(root))# 反序列化:还原树结构defstr2tree(root):
s = string(root)# 序列化# print(s)# 利用分隔好的字符串生成的数组生成一个迭代器。也可以遍历字符串,生成数组
vallist =iter(s.split(' '))deftotree():# 通过next不断调用vallist这个迭代器里的元素,相当于for循环
val =next(vallist)# print(val)if val =='#':returnNoneelse:
head = BinaryTree(int(val))
head.child_l = totree()
head.child_r = totree()return head
head = totree()return head
print('反序列化结果:', str2tree(root).data)# 验证反序列化结果
newtree = str2tree(root)print('验证反序列化结果:', string(newtree))
# 层序序列化defstring1(root):ifnot root:return[]
res =[]
queue =[root]while queue:
p = queue.pop(0)if p:
res.append(str(p.data))
queue.append(p.child_l)
queue.append(p.child_r)else:
res.append('#')return' '.join(res)print('序列化结果:', string1(root))# 反序列化defstr2tree1(root):
s = string1(root)# 序列化if s ==[]:returnNone
val = s.split(' ')
i =1
head = BinaryTree(int(val[0]))
queue =[head]while queue:
p = queue.pop(0)if val[i]!='#':
p.child_l = BinaryTree(int(val[i]))
queue.append(p.child_l)
i +=1if val[i]!='#':
p.child_r = BinaryTree(int(val[i]))
queue.append(p.child_r)
i +=1return head
print('反序列化结果:', str2tree1(root).data)# 验证反序列化结果
newtree = str2tree1(root)print('验证反序列化结果:', string1(newtree))
4、平衡二叉树,左右子树高度差不超1(不一定是满树)、满二叉树(一定是平衡树)
'''
平衡二叉树:以每个节点为头节点的子树都是平衡树
① 左平衡否
② 右平衡否
③ 左高乎?
④ 右高乎?
进阶:树形dp
'''# 每个子树都要判断是否平衡# 自底向上defIsBalanced(root):defpsf(p):if p ==None:return0
left = psf(p.child_l)if left ==-1:return-1
right = psf(p.child_r)if right ==-1:return-1ifabs(left-right)>1:return-1return1+max(right,left)return psf(root)!=-1print('是平衡数:',IsBalanced(root))# 自上而下defIsBalanced2(root):deftreehight(root):ifnot root:return0
left = treehight(root.child_l)
right = treehight(root.child_r)returnmax(left, right)+1ifnot root:returnTrue# 判断子树是否平衡
left = treehight(root.child_l)
right = treehight(root.child_r)ifabs(right - left)>1:returnFalsereturn balance_tree(root.child_l)and balance_tree(root.child_r)print('是平衡数:',IsBalanced2(root))
5、搜索二叉树
'''
任何一个节点的左节点值比他小,右节点值比他大,即中序遍历结果升序
通常二叉树不含重复节点
'''# 判断是否为搜索二叉树defisBST(root):ifnot root:return
stack =[]
pre =float('-inf')while stack or root:if root:
stack.append(root)
root = root.child_l
else:
root = stack.pop()print(root.data, end =', ')if root.data > pre:
pre = root.data
root = root.child_r
else:returnFalsereturnTrueprint('是搜索二叉树:', isBST(root))
6、完全二叉树
'''
完全二叉树:若二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,
第 h 层所有的结点都连续集中在最左边。
判断:
层序遍历过程中:
① 某节点有右子无左子,False
② 某节点左右孩子不全,后面所有节点必须是叶子节点
'''defisCBT(root):ifnot root:returnTrue
flag =False
queue =[root]while queue:
head = queue.pop(0)
l = head.child_l
r = head.child_r
# 情况 1if l ==Noneand r !=None:returnFalse# 情况 2if flag and(l !=Noneor r !=None):returnFalseif l:
queue.append(l)if r:
queue.append(r)# 某节点左右孩子不全,改变flag ,下一次判断条件 2 else:
flag =TruereturnTrueprint('是完全二叉树:', isCBT(root))# 数组实现堆,扩容代价,二叉树实现则没有