二叉树的遍历python3版本


输出遍历序列实际上就是将遍历中的print语句改成储存在结果列表中即可,这里作为练习都写了一遍。

先序遍历

迭代

入栈出栈顺序

# 先序遍历打印
def preorderTraversal(root):
	if not root:
		return
	stack = [root]
	while stack:
		cur = stack.pop()
		print(cur.val)
		if cur.right:
			stack.append(cur.right)
		if cur.left:
			stack.append(cur.left)
# 输出先序遍历序列
def preorderTraversal(root):
	res = []
	if not root:
		return res
	stack = [root]
	while stack:
		cur = stack.pop()
		res.append(cur.val)
		if cur.right:
			stack.append(cur.right)
		if cur.left:
			stack.append(cur.left)
	return res

递归

# 打印二叉树
def preorderTraversal(root):
	if not root:
		return 
	print(root.val)
	preorderTraversal(root.left)
	preorderTraversal(root.right)
# 输出先序遍历序列
res = []
def preorderTraversal(root):
	if not root:
		return 
	res.append(root.val)
	preorderTraversal(root.left)
	preorderTraversal(root.right)
print(res)

中序遍历

迭代

# 打印中序遍历结果
def inorderTraverse(root):
	stack = []
	while stack or root:
		while root:
			stack.append(root)
			root = root.left
		root = stack.pop()
		print(root.val)
		root = root.right
# 输出中序遍历序列
def inorderTraverse(root):
	res= []
	stack = []
	while stack or root:
		while root:
			stack.append(root)
			root = root.left
		root = stack.pop()
		res.append(root.val)
		root = root.right
	return res

递归

#打印中序遍历结果
def inorderTraverse(root):
	if not root:
		return 
	inorderTraverse(root.left)
	print(root.val)
	inorderTraverse(root.right)
# 输出中序遍历序列
res = []
def	inorderTraverse(root):
	if not root:
		return
	inorderTraverse(root.left)
	res.append(root.val)
	inorderTraverse(root.right)

后序遍历

迭代

后序遍历的最终结果做逆序,就是先序遍历中交换访问左孩子和右孩子的顺序的结果。因此只要把先序遍历中左右子树的访问顺序对调,最后在做一个逆序就得到后序遍历的结果。

# 打印后序遍历结果
# 使用两个栈结构
# 第一个栈进栈顺序:左节点->右节点->根节点
# 第一个栈弹出顺序: 根节点->右节点->左节点(先序遍历栈弹出顺序:根->左->右)
# 第二个栈存储为第一个栈的每个弹出依次进栈
# 最后第二个栈依次出栈
def postorderTraverse(root):
	if not root:
		return 
	stack1, stack2 = [root], []
	while stack1:
		root = stack1.pop()
		stack2.append(root)
		if root.left:
			stack1.append(root.left)
		if root.right:
			stack1.append(root.right)
	while stack2:
		print(stack2.pop().val)
def	postorderTraverse(root):
	if not root:
		return 
	stack1, stack2 = [root], []
	while stack1:
		root = stack1.pop()
		stack2.append(root)
		if root.left:
			stack1.append(root.left)
		if root.right:
			stack1.append(root.right)
	return [stack2[i].val for i in range(len(stack2)-1, -1, -1)]

递归

队列

# 打印遍历结果
def postorderTraverse(root):
	if not root:
		return 
	postorderTraverse(root.left)
	postorderTraverse(root.right)
	print(root.val)
# 输出后序遍历序列
res = []
def postorderTraverse(root):
	if not root:
		return 
	postorderTraverse(root.left)
	postorderTraverse(root.right)
	res.append(root.val)

层次遍历

迭代

def layerTraverse(root):
	if not root:
		return
	queue = []
	queue.append(root)
	while queue:
		cur = queue.pop(0)
		print(cur.val)
		# 输出遍历序列时,只需要增加结果列表,并将上句改成res.append(cur.val)
		if cur.left:
			queu.append(cur.left)
		if cur.right:
			queue.append(cur.right)

广度优先搜索BFS

就是层次遍历

应用

问题描述:将二叉树的每一层以列表的形式返回,最终返回结果是由各层列表组成的列表
想法:整体思路还是层次遍历,问题的关键在于如何区分不同层的元素,因为可能二叉树不是完全二叉树,不能简单的使用每一层节点的数量进行判断。

法1

使用不同的序列存储当前层和下一层的节点,当前层访问结束后令其等于下一层的节点列表

def printlayer(root):
	ans = []
	if not root:
		return ans
	queue = [root]
	while queue:
		#当前层节点的值列表
		curval = []  
		# 下一层节点
		nextqueue = []
		for cur in queue:
			curval.append(cur.val)
			if cur.left:
				nextqueue.append(cur.left)
			if cur.right:
				nextqueue.append(cur.right)
		ans.append(curval)
		queue = nextqueue
	return ans 
法2

在遍历当前层前,记录当前层节点的个数,只访问指定数目的节点

def printlayer(root):
    ans = []
    if not root:
        return ans 
    queue = [root]
    while queue:
        curval = []
        curlength = len(queue)
        for i in range(curlength):
            cur = queue.pop(0)
            curval.append(cur.val)
            if cur.left:
                queue.append(cur.left)
            if cur.right:
                queue.append(cur.right)
        ans.append(curval)
    return ans 

深度优先搜索DFS

深度优先搜索对应的就是先序遍历、中序遍历要和后序遍历三种遍历方式

常见的使用是先序遍历的方式。

应用

返回从根节点到叶子节点的所有路径,每条路径为一个列表

法1

使用深度优先搜索递归实现。递归函数的含义是:给出当前节点以及到达当前节点的路径,从当前节点出发先序遍历,只有当遇到叶子节点时才将路径放入最终的结果中。

def construct_paths(root, path):
	if root:
		path += str(root.val)
		if not root.left and not root.right:
			#当前节点为叶子节点,将路径加入最终的结果中
			paths.append(path)
		else:
		# 当前节点不是叶子节点,继续递归遍历
			path += '->'
			construct_paths(root.left, path)
			construct_paths(root.right, path)
paths = []
construct_paths(root, '')
法2

使用深度优先搜索迭代实现

class Solution {
    fun binaryTreePaths(root: TreeNode?): List<String> {

        val result = LinkedList<String>()

        val stack: Deque<TreeNode> = LinkedList()
        val helperStack: Deque<StringBuilder> = LinkedList<StringBuilder>()

        if (null != root) {
            stack.push(root)
            helperStack.push(StringBuilder())
        }

        while (!stack.isEmpty()) {
            val node = stack.pop()
            val path = helperStack.pop()
            path.appendChar(node.`val`)
            if (null == node.left && null == node.right) {
                // 到达叶子节点
                result.add(path.toString())
            } else {
                if (null != node.right) {
                    stack.push(node.right)
                    helperStack.push(StringBuilder(path))
                }
                if (null != node.left) {
                    stack.push(node.left)
                    helperStack.push(StringBuilder(path)) // LIFO
                }
            }
        }

        return result
    }

    private fun StringBuilder.appendChar(num: Int) {
        if (length == 0) {
            append("$num")
        } else {
            append("->$num")
        }
    }
}

注:

法2代码来源:(侵删)
作者:pengxurui
链接:https://leetcode-cn.com/problems/binary-tree-paths/solution/kotlin-di-gui-dfs-bfs-by-pengxurui/
来源:力扣(LeetCode)

法3

使用广度优先搜索,对于每个节点,如果有孩子节点,依次将对应的孩子节点拼接到对应的路径上。

def treepath(root):
    paths = []
    if not root:
        return paths
    
    node_queue = collections.deque([root])
    path_queue = collections.deque([str(root.val)])

    while node_queue:
    	#node和path的最后一个节点相同
        node = node_queue.popleft()
        path = path_queue.popleft()

        if not node.left and not node.right:
            paths.append(path)
        else:
            if node.left:
                node_queue.append(node.left)
                path_queue.append(path + '->' + str(node.left.val))
            if node.right:
                node_queue.append(node.right)
                path_queue.append(path + '->' + str(node.right.val))
    return paths
	
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值