python实现树的遍历

二叉树的遍历是指按照某种顺序依次访问树中的所有节点一次。

四种遍历方式分别是:先序遍历、中序遍历、后序遍历、层序遍历。其中前三种属于深度优先遍历(DFS),后一种属于广度优先遍历(BFS)。

首先声明节点类

class TreeNode:
	def __init__(self, x):
		self.val = x
		self.left = None
		self,right = None

二叉树的先序遍历

 若二叉树为空树,则空操作;否则,(1)访问根结点;(2)先序遍历左子树;(3)先序遍历右子树。

递归实现:

def preOrder(self, root):
    if not root:
        return 
    # 先访问根节点
    print(root.val)
    # 递归访问左子树
    preorder(root.left)
    # 访问右子树
    preorder(root.right)

迭代实现:

def pre(self, root):
	# 将 root放入栈顶
	stack = [root]
	while stack:
		# 取栈顶元素
		s = stack.pop()
		if s:
			print(s.val)
			# 由于栈的先进后出特性 先放入右孩子 再放入左孩子
			stack.append(s.right)
			stack.append(s.left)

二叉树的中序遍历

 若二叉树为空树,则空操作;否则,(1)中序遍历左子树;(2)访问根结点;(3)中序遍历右子树。

递归实现:

def midOrder(self, root):
	if not root:
		return
	# 先访问左节点 再访问根节点 最后访问右节点
	midOrder(root.left)
	print(roo.val)
	midOrder(root.right)

迭代实现:

# 对于树的遍历 ,基本会用到栈这个数据结构
def inOrder(self,root):
	stack = []
	while stack or root:
		# 当root节点存在,一直往下遍历 直到遍历到叶节点
		while root:
			stack.append(root)
			root = root.left
		# 当前节点为None时 出栈一个节点打印出节点的value值
		root = satck.pop()
		print(root.val)
		# 也系欸但的孩子肯定为空 所以就会弹出栈中叶节点的父节点,当左子树完全遍历完就会遍历右子树
		root = root.right

二叉树的后序遍历

 若二叉树为空树,则空操作;否则,(1)后序遍历左子树;(2)后序遍历右子树;(3)访问根结点。

递归实现:

def postOrder(self, root):
	if not root:
		return 
	postOrder(root.left)
	postOrder(root.right)
	print(root.val)

迭代实现:

法一:

def post(self, root):
	stack = []
	while root or stack:
		# 下行遍历 一直遍历到叶节点
		while root:
			# 将根节点放入放入栈中
			stack.append(root)
			# 能左就左 能右就右
			if root.left:
				root = root.left
			if root.right:
				root = root.right
		s = stack.pop()
		print(s.val)
		# 如果当前节点是上一节点的左子节点,则遍历右子节点
        if stack and s == stack[-1].left: 
            root = stack[-1].right
        else:
            root = None

法二:在先序遍历的基础上稍加改动

# 先序遍历 顺序是 根左右 ,后续遍历是 左右根  
# 所以可以将res数组的值反过来输出
def post_2(self, root):
	stack = [root]
	res = []
	while stack:
		s = stack.pop()
		res.append(s.val)
		stack.append(s.left)
		satck.append(s.right)
	return res[::-1]

二叉树的层次遍历

从上往下、从左至右依次打印树的节点

写法一:利用队列

def levelOrder(self, root):
	# 如果根节点不存在,返回空列表
	if not root:
		return []
	# 结果列表
	res = []
	# 将根节点放入队列
	queue = [root]
	while queue:
		# 获取当前队列的长度 也就是这一层的节点数
		size = len(queue)
		tmp = []

		# 将队列中的元素拿出来 放到临时list中
		# 如果左右子树不为空,放入队列中
		for _ in range(size):
			# 弹出队列中的节点
			r = queue.pop(0)
			# 将r的值 存进临时列表中
			tmp.append(r.val)
			if r.left:
				queue.append(r.left)
			if r.right:
				queue.append(r.right)
		res.append(tmp)
	return res

写法二:利用collections.deque 双向队列 

def levelOrder(self, root):
    """
    :type root: TreeNode
    :rtype: List[List[int]]
    """
    # 创建队列
    queue = collections.deque()
    queue.append(root)
    # 结果集
    res = []
    while queue:
        size = len(queue)
        level = []
        for _ in range(size):
        	# 弹出左边第一个元素
            cur = queue.popleft()
            if not cur:
                continue
            level.append(cur.val)
            queue.append(cur.left)
            queue.append(cur.right)
        if level:
            res.append(level)
    return res

二叉树的一些基本操作总结:

1.二叉树的最大深度

def maxDepth(self, root):
	if not root:
		return 0
	return max(maxDepth(root.left), maxDepth(root.right)) + 1

2.二叉树的最小深度

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。可以通过递归求左右节点的最小深度的较小值,也可以层序遍历找到第一个叶子节点所在的层数。

递归实现:

def minDepth(self, root):
    if not root:
        return 0    
    if not root.left and not root.right:
        return 1 
    if not root.right:
        return 1+self.minDepth(root.left)
    if not root.left:
        return 1+self.minDepth(root.right)
    return 1+min(self.minDepth(root.left),self.minDepth(root.right))

迭代实现:

def min_Depth(self, root):
	if not root:
		return 0
	ans , count = [root], 1

	# 遍历完所有节点
	while ans:
		n = len(ans)
		# 遍历完某一层的节点
		for _ in range(n):
			r = ans.pop(0)
            if r:
            	# 算法遍历每一层 发现某一层的某个节点没有子树 返回count
                if not r.left and not r.right:
                    return count
                # 如果左孩子存在 加入栈
                ans.append(r.left if r.left else [])
                ans.append(r.right if r.right else [])
	    count+=1 

	return count

未完待续 ,后续还会补充更多知识点。

参考链接:

https://www.cnblogs.com/anzhengyu/p/11083568.html

https://www.cnblogs.com/bjwu/p/9284534.html

猜你喜欢

转载自blog.csdn.net/candice5566/article/details/107940879