树的递归遍历
1. 列表存储树
1.1 前序遍历
def preorder(tree,n,i):
l=2*i+1
r=2*i+2
print(tree[i])
if l<n:
preorder(tree,n,l)
if r<n:
preorder(tree,n,r)
tree=["A","B","C","D","E","F","G","H","I","J"]
preorder(tree,len(tree),0)
1.2 中序遍历
def midorder(tree,n,i,mid):
l=2*i+1
r=2*i+2
if l<n:
midorder(tree,n,l,mid)
mid.append(tree[i]
if r<n:
midorder(tree,n,r,mid)
return mid
tree=["A","B","C","D","E","F","G","H","I","J"]
mid=[]
midorder(tree,len(tree),0,mid)
print(mid)
1.3 后序遍历
def enorder(tree,n,i,end):
l=2*i+1
r=2*i+2
if l<n:
enorder(tree,n,l,end)
if r<n:
enorder(tree,n,r,end)
end.append(tree[i])
tree=["A","B","C","D","E","F","G","H","I","J"]
end=[]
enorder(tree,len(tree),0,end)
print(end)
2. 链表存储树(treeNode类)
使用Node类为根节点以及左右节点创建占位符
def TreeNode:
def __init__(self.val):
self.left=None
self.right=None
self.val=val
插入结点构建完全二叉树
def insertion(root,leftval,rightval=None):
left=TreeNode(leftval)
root.left=left
if rightval is None:
right=None
else:
right=TreeNode(rightval)
root.right=right
return left,right
def build_tree(vals,i):
queue=[]
root=TreeNode(vals[i])
queue.append(root)
index=[]
index.append(i)
n=len(vals)
while len(queue)>0:
i=index.pop(0)
vertex=queue.pop(0)
l=2*i+1
r=2*i+2
if l<n:
index.append(l)
if r<n:
index.append(r)
left,right=insertion(vertex,vals[l],vals[r])
queue.append(left)
queue.append(right)
else:
insertion(vertex,vals[l],None)
break
else:
break
return root
vals=["A","B","C","D","E","F","G","H","I","J"]
root=build_tree(vals,0)
2.1 前序遍历
def preorder(root):
if root is None:
return
print(root.val)
if root.left:
preorder(root.left)
if root.right:
preorder(root.right)
preorder(root)
2.2 中序遍历
def midorder(root):
if root is None:
return
if root.left:
midorder(root.left)
print(root.val)
if root.right:
midorder(root.right)
midorder(root)
2.3 后序遍历
def endorder(self, root):
if root is None:
return
if root.left:
endorder(root.left)
if root.right:
endorder(root.right)
print(root.val)
endorder(root)
树的非递归遍历
1. 列表存储树
层次遍历(BFS于列表存储的完全二叉树)
def BFSorder(tree,n):
queue=[]
queue.append(tree[0])
index=[]
index.append(0)
bfs=[]
while len(queue)>0:
vertex=queue.pop(0)
bfs.append(vertex)
ix=index.pop(0)
l=2*ix+1
r=2*ix+2
if l<n:
queue.append(tree[l])
index.append(l)
if r<n:
queue.append(tree[r])
index.append(r)
return bfs
tree=["A","B","C","D","E","F","G","H","I","J"]
bfs=BFSorder(tree,len(tree))
print(bfs)
2. 链表存储树(treeNode类)
2.1 前序遍历——栈
def preOrder(root):
if not root:return []
stack=[root]
res=[]
while stack:
root=stack.pop()
res.append(root.val)
if root.right:stack.append(root.right)
if root.left:stack.append(root.left)
return res
2.2 中序遍历——栈
中序遍历需要一直遍历到左孩子结点为空的结点才进行访问,然后再访问右孩子。
def inOrder(root):
if not root:return []
stack,res=[],[]
while stack or root:
while root:
stack.append(root)
root=root.left
if stack:
root=stack.pop()
res.append(root.val)
root=root.right
return res
2.3 后序遍历——栈
def postOrder(root):
if not root:return []
stack=[root]
res=[]
while stack:
root=stack.pop()
res.append(root.val)
if root.right:stack.append(root.right)
if root.left:stack.append(root.left)
return res[::-1]
def postOrder1(root):
if not root:return []
stack,ans=[],[]
while stack or root:
while root:
stack.append(root)
root= root.left if root.left else root.right
# 循环结束说明走到了叶子节点,没有左右子树了,该叶子节点即为当前栈顶元素
root=stack.pop()
ans.append(root.val)
if stack and stack[-1].left==root:# 若栈不为空且当前节点是栈顶元素的左节点
root=stack[-1].right # 则转向遍历右节点
else:
root=None# 没有左子树或右子树,强迫退栈
return ans
2.4 层次遍历——队列
def graOrder(self, root):
if not root:return []
queue= [root]
while queue:
res = []
for item in queue:
print(item.val)
if item.left:res.append(item.left)
if item.right:res.apppend(item.right)
queue = res
graorder(root)
def graOrder(root):
if not root:return []
queue,res = [root],[]
while queue:
root = queue.pop(0)
res.append(root.val)
if root.left:queue.append(root.left)
if root.right:queue.append(root.right)
return res
二叉树的深度
1. 层次遍历时记录
def maxDepth(root):
if not root:return 0
queue,res=[root],0
while queue:
tmp=[]
for node in queue:
if node.left:tmp.append(node.left)
if node.right:tmp.append(node.right)
queue=tmp
res+=1
return res
2. 递归
def maxDepth(root):
if not root:return 0
return max(maxDepth(root.left),maxDepth(root.right))+1