树
定义:
有限节点组成一个具有层次关系的集合
分类:
(重点)二叉树 — 》》 完全二叉树
1.除最外层 外,其余各层均满了(1对2)
2.最外层要从左向右连续紧密排序
树的表示:
链式存储:
数据放到节点中,节点还存放子节点的地址(引用)
二叉树
1.创建完全二叉树(按照完全二叉树的规则挂树)
1.若树为空,挂到根节点
2.根节点入队
3.出队依次判断是否有左右孩子,没有则挂树
4.依次入队左右孩子,重复步骤3
class Node(object):
def __init__(self,item):
self.item = item
self.lchild = None
self.rchild = None
class Tree(object):
def __init__(self):
self.root= None
def add(self,item):
node = Node(item)
# 若树为空,挂到根节点
if self.root == None:
self.root = node
return
# 根节点入队
que = []
que.append(self.root)
# 出队一次判断是否有左右孩子,没有则挂树
while len(que) >0:
# 出队
cur = que.pop(0)
if cur.lchild is None:
cur.lchild = node
return
elif cur.rchild is None:
cur.rchild = node
return
# 依次入队左右孩子,重复步骤3
else:
que.append(cur.lchild)
que.append(cur.rchild)
if __name__ == '__main__':
tr = Tree()
tr.add(2)
tr.add(1)
tr.add(3)
2 广度优先遍历
1 根节点入队
2 出队打印,依次入队左右孩子
3 重复步骤2 直到队列空
def breath_travel(self):
if self.root is None:
return
# 根节点入队
que = []
que.append(self.root)
# 出队打印,依次入队左右孩子
while len(que) >0:
cur = que.pop(0)
print(cur.item,end="--")
if cur.lchild is not None:
que.append(cur.lchild)
if cur.rchild is not None:
que.append(cur.rchild)
# 重复步骤2
# print()
# 直到队列空
3 深度优先遍历
先序:根–》左子树–》右子树
中序:左子树–》根–》右子树
后序:左子树–》右子树–》根
递归实现
def preorder(self, root):
if root is None:
return
print(root.item,end="--")
self.preorder(root.lchild)
self.preorder(root.rchild)
def inorder(self, root):
if root is None:
return
self.inorder(root.lchild)
print(root.item, end="--")
self.inorder(root.rchild)
def postorder(self, root):
if root is None:
return
self.postorder(root.lchild)
self.postorder(root.rchild)
print(root.item, end="--")
查找节点
def search(self, root, item):
if root is None:
return None
if root.item == item:
return root
lres = self.search(root.lchild, item)
if lres is not None:
return lres
rres = self.search(root.rchild, item)
if rres is not None:
return rres
return None
if __name__ == '__main__':
tr = Tree()
tr.add(0)
tr.add(1)
tr.add(2)
tr.add(3)
tr.add(4)
tr.add(5)
tr.add(6)
tr.add(7)
tr.add(8)
tr.add(9)
nodeA = tr.search(tr.root, 7)
nodeB = tr.search(tr.root, 3)
查找公共祖先
1.判断两个节点是否同时属于节点x 的左孩子 === 》 返回nodex的左孩子
2.判断两个节点是否同时属于节点x 的右孩子 === 》 返回nodex的右孩子
3.返回nodex
def pub_dad(self,root,nodeA,nodeB):
if root is None:
return None
if root == nodeA or root == nodeB:
return root
ldad = self.pub_dad(root.lchild, nodeA, nodeB)
rdad = self.pub_dad(root.rchild, nodeA, nodeB)
if ldad is None:
return rdad
elif rdad is None:
return ldad
else:
return root
if __name__ == '__main__':
tr = Tree()
tr.add(0)
tr.add(1)
tr.add(2)
tr.add(3)
tr.add(4)
tr.add(5)
tr.add(6)
tr.add(7)
tr.add(8)
tr.add(9)
nodeA = tr.search(tr.root, 7)
nodeB = tr.search(tr.root, 3)
node_dad = tr.pub_dad(tr.root, nodeA, nodeB)
print(node_dad.item)