数据结构算法-树
   
    最近在刷leetcode的树,整理了常用遍历代码
    
    包含树的层次遍历(
    
     广度优先遍历
    
    )-两种方法
   
- BFS通用模板 ★★★★★
- 标记法★★★★
    前中后序遍历(
    
     深度优先遍历
    
    )-六种方法
   
- 暴力递归 ★★★
- 
     DFS
 
 通用
 
 递归(非暴力递归) ★★★★
- 非递归迭代栈(前+后),类似层次遍历实现★★★
- 
     非递归通用迭代栈(前+
 
 中
 
 +后)★★★★★
- 标记法迭代栈(前中后)★★★★★
- 莫里斯遍历
以及N叉树的遍历-(递归与迭代方法)
    以及由
    
     前序+中序
    
    确定二叉树 and
    
     中序+后序
    
    确定二叉树
    
    ####################
    
    ####################
   
    
    
    层次遍历(广度优先遍历)★★★★★
   
1.BFS通用模板
#BFS通用模板,层次遍历通用:
#使用队列实现
def levelOrder(root):
	if not root:
		return []
	queue=[root]
	ans=[]
	while queue:
		a=[]     #方便保存每一层的数据
		for j in range(len(queue)):  #将每一层分割开
			cur=queue.pop(0)
			if not cur:
				return 
			a.append(cur.val)
			if cur.left:
				queue.append(cur.left)
			if cur.right:
				queue.append(cur.right)
		ans.append(a)
	return ans	
2.标记法
#**标记法**:队列实现
#0代表当前未访问,1代表当前已访问
def levelOrder(root):
	ans=[]
	queue=[(0,root)]
	while queue:
		flag,cur= queue.pop(0)   #先进先出
		if not cur:continue
		if flag == 0:
			queue.append((1,cur))
			queue.append((0,cur.left))
			queue.append((0,cur.right))
		else:
			ans.append(cur.val)
	return ans
#########################################
    
    
    前中后序遍历(深度优先遍历)
   
**中序非递归遍历最重要,面试经常被问到~**
1 . 暴力递归:
def preorderTraversal(root):
	if not root:
		return []
	return [root.val]+self.preorderTraversal(root.left)+self.preorderTraversal(root.right)  #前序
	return self.inorderTraversal(root.left)+[root.val]+self.inorderTraversal(root.right)  #中序
	return self.postorderTraversal(root.left)+self.postorderTraversal(root.right)+[root.val]  #后序
2 . DFS通用递归:
def preorderTraversal(root):   #前序
	def DFS(cur):
		if not cur:
			return 
		ans.append(cur.val)
		DFS(cur.left)
		DFS(cur.right)
	ans=[]
	DFS(root)
	return ans
#中序与后序只需要更改DFS函数体内,三行代码的顺序
3 . 非递归迭代栈(前+后)
#非递归迭代,用栈实现,类似层次遍历中的队列实现
#前序:
def preorderTraversal(root):
	if not root:
		return []
	stack=[root]
	ans=[]
	while stack:
		node=stack.pop()
		ans.append(node.val)
		if node.right:         #先右再左,不能反 ,使得出栈时候左先出
			stack.append(node.right)
		if node.left;
			stack.append(node.left)
	return ans
#后序
def postorderTraversal(root):
	if not root:
		return []
	stack=[root]
	ans=[]
	while stack:
		node=stack.pop()
		ans.append(node.val)
		if node.left:             #进:先左再右,出:先右再左
			stack.append(node.left)
		if node.right:
			stack.append(node.right)
	return ans[::-1]
    4 . 非递归通用栈(前
    
     中
    
    后)-
    
     中最重要
    
   
#前序:★★★★
def preorderTraversal(root):
	if not root:
		return []
	stack=[]
	ans=[]
	cur=root
	while cur or stack:
		while cur:            #找到每颗子树的最左下角
			ans.append(cur.val)
			stack.append(cur)
			cur=cur.left
		cur=stack.pop()
		cur=cur.right
	return ans
#中序:★★★★★
def inorderTraversal(root):
	if not root:
		return []
	stack=[]
	ans=[]
	cur=root
	while cur or stack:
		while cur:            #找到每颗子树的最左下角
			stack.append(cur)
			cur=cur.left
		cur=stack.pop()
		ans.append(cur.val)
		cur=cur.right
	return ans
#后序:★★★★
def postorderTraversal(root):
	if not root:
		return []
	stack=[]
	ans=[]
	cur=root
	while cur or stack:
		while cur:
			ans.append(cur.val)
			stack.append(cur)
			cur=cur.right         #相比前序,后序应先找到最右下子树,得到:根-右-左,最后反转
		cur=stack.pop()
		cur=cur.left
	return ans[::-1]
5 . 标记法迭代:
#**标记法**:栈实现
#0代表当前未访问,1代表当前已访问
def inorderTraversal(root):   #中序
	ans=[]
	stack=[(0,root)]
	while stack:
		flag,cur= stack.pop()
		if not cur:continue
		if flag == 0:
			stack.append((0,cur.right))
			stack.append((1,cur))
			stack.append((0,cur.left))
		else:
			ans.append(cur.val)
	return ans
#前序:
		......
		if flag == 0:
			stack.append((0,cur.right))
			stack.append((0,cur.left))
			stack.append((1,cur))
		......
#后序:
		......
		if flag == 0:
			stack.append(1,cur)
			stack.append((0,cur.right))
			stack.append((0,cur.left))
		......
    
    
    N叉树的遍历(递归+迭代)
   
#1.递归解法
def preorder(root):
	res=[]
	def DFS(root):
		if not root:return 
		res.append(root.val)
		for child in root.children:
			DFS(child)
	DFS(root)
	return res
#后序只需要调整函数体内部顺序就行
#2.迭代解法
def preorder(root):
	if not root:return[]
	stack=[root]
	res=[]
	while stack:
		cur=stack.pop()
		res.append(cur.val)
		for child in cur.children[::-1]:
			stack.append(child)
	   #stack.extend(cur.children[::-1])
	return res  
def postorder(root):
	if not root:return []
    stack=[root]
    res=[]
    while stack:
        cur=stack.pop()
        res.append(cur.val)
        for child in cur.children:
             stack.append(child)
        #stack.extend(cur.children)
    return res[::-1]        
    
    
    二叉树的确定(前+中 and 中+后)
   
前序/后序+中序序列可以唯一确定一棵二叉树,必须包含中序,否则无法确定树的形状
class TreeNode:   #定义树节点
	def __init__(self,val=0,left=None,right=None):
		self.val=val
		self.left=left
		self.right=right
		
#前序+中序
def buildTree(self, preorder: List[int], inorder: List[int]):
	if not preorder:return None
	root=TreeNode(preorder[0])      #前序第一项为根节点
	index=inorder.index(root.val)    #找到中序根节点,其左右两侧即为左子树和右子树
	root.left=self.buildTree(preorder[1:1+index],inorder[:index])
	root.right=self.buildTree(preorder[1+index:],inorder[index+1:])
	return root
#中序+后序
def buildTree(self, inorder: List[int], postorder: List[int]):
	if not postorder:return None
	root=TreeNode(postorder[-1])       #后序最后一项为根节点
	index_1=inorder.index(root.val)    
	root.left=self.buildTree(inorder[:index],postorder[:index])
	root.right=self.buildTree(inorder[index+1:],postorder[index:-1])
	return root
 
版权声明:本文为weixin_45469590原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
