树遍历(BFS+DFS(递归+非递归))-python代码整理

数据结构算法-树

最近在刷leetcode的树,整理了常用遍历代码
包含树的层次遍历(广度优先遍历)-两种方法

  • BFS通用模板 ★★★★★
  • 标记法★★★★

前中后序遍历(深度优先遍历)-六种方法

  1. 暴力递归 ★★★
  2. DFS通用递归(非暴力递归) ★★★★
  3. 非递归迭代栈(前+后),类似层次遍历实现★★★
  4. 非递归通用迭代栈(前++后)★★★★★
  5. 标记法迭代栈(前中后)★★★★★
  6. 莫里斯遍历

以及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
Python中的二叉树遍历可以使用广度优先搜索(BFS)和深度优先搜索(DFS)两种方法。 BFS(广度优先搜索)是一种逐层遍历二叉树的方法。从根节点开始,按照层级顺序依次访问每个节点,先访问左子节点,再访问右子节点。具体实现可以使用队列来辅助实现。以下是BFS的实现方式: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def bfs(root): if not root: return [] queue = [root] result = [] while queue: node = queue.pop(0) result.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) return result ``` DFS(深度优先搜索)是一种先访问根节点,然后递归地访问左子和右子的方法。DFS有三种常见的遍历方式:前序遍历、中序遍历和后序遍历。以下是DFS的实现方式: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def dfs_preorder(root): if not root: return [] result = [] result.append(root.val) result += dfs_preorder(root.left) result += dfs_preorder(root.right) return result def dfs_inorder(root): if not root: return [] result = [] result += dfs_inorder(root.left) result.append(root.val) result += dfs_inorder(root.right) return result def dfs_postorder(root): if not root: return [] result = [] result += dfs_postorder(root.left) result += dfs_postorder(root.right) result.append(root.val) return result ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值