赞
踩
中序遍历:左 -> 中 -> 右
练习地址:94. 二叉树的中序遍历
- # Definition for a binary tree node.
- class TreeNode(object):
- def __init__(self, val=0, left=None, right=None):
- self.val = val
- self.left = left
- self.right = right
-
-
- class Solution(object):
-
- def dfs(self, root, res):
- if not root:
- return
- self.dfs(root.left, res)
- res.append(root.val)
- self.dfs(root.right, res)
-
- def inorderTraversal(self, root):
- res = []
- self.dfs(root, res)
- return res
-
-
- if __name__ == '__main__':
- # 创建一个二叉树
- tree = TreeNode(1)
- tree.left = TreeNode(2)
- tree.right = TreeNode(3)
- tree.left.left = TreeNode(4)
- tree.left.right = TreeNode(5)
- tree.right.right = TreeNode(6)
-
- # 执行中序遍历
- sol = Solution()
- print(sol.inorderTraversal(tree)) # [4, 2, 5, 1, 3, 6]
详细的测试代码请参考:算法:Java构建二叉树并递归实现二叉树的前序、中序、后序遍历-CSDN博客
- class Solution {
- //中序遍历
- public List<Integer> inorderTraversal(TreeNode root) {
- List<Integer> res = new ArrayList<Integer>();
- inorder(root, res);
- return res;
- }
- public void inorder(TreeNode root, List<Integer> res) {
- if (root == null) {
- return;
- }
- inorder(root.left, res);
- res.add(root.val);
- inorder(root.right, res);
- }
- }
- # Definition for a binary tree node.
- class TreeNode(object):
- def __init__(self, val=0, left=None, right=None):
- self.val = val
- self.left = left
- self.right = right
-
-
- class Solution(object):
-
- def inorderTraversal(self, root):
- res = []
- stack = []
- while root or stack:
- while root: # 先遍历完所有左节点,放入栈中
- stack.append(root)
- root = root.left
- root = stack.pop() # 将当前节点出栈
- res.append(root.val)
- # 将右节点作为根节点重新开始遍历,直到 root 和 栈 都为空为止
- root = root.right
- return res
-
-
- if __name__ == '__main__':
- # 创建一个二叉树
- tree = TreeNode(1)
- tree.left = TreeNode(2)
- tree.right = TreeNode(3)
- tree.left.left = TreeNode(4)
- tree.left.right = TreeNode(5)
- tree.right.right = TreeNode(6)
-
- # 执行中序遍历
- sol = Solution()
- print(sol.inorderTraversal(tree)) # [4, 2, 5, 1, 3, 6]
- class Solution {
- public List<Integer> inorderTraversal(TreeNode root) {
- List<Integer> res = new ArrayList<Integer>();
- if (root == null) {
- return res;
- }
- Deque<TreeNode> stack = new LinkedList<TreeNode>();
- TreeNode node = root;
- while(!stack.isEmpty() || node != null){
- while (node != null) {
- stack.push(node);
- node = node.left;
- }
- node = stack.pop();
- res.add(node.val);
- node = node.right;
- }
- return res;
- }
- }
仔细看代码注释与图解,其实原理很简单。(该方法会改变树的结构)
- # Definition for a binary tree node.
- class TreeNode(object):
- def __init__(self, val=0, left=None, right=None):
- self.val = val
- self.left = left
- self.right = right
-
- '''
- 主要思想:从上往下,把每一个节点与其右子树挂到左子树的最右边
- 该方法相比前两种方法,主要是节省了空间,空间复杂度从O(n)变成了O(1)
- '''
- class Solution(object):
-
- def inorderTraversal(self, root):
- res = []
- while root:
- if root.left: # 如果当前节点存在左子树,则找到其最右边的子节点
- pre = root.left
- while pre.right: # 找到其最右边的子节点
- pre = pre.right
- # 把root赋值给temp,把temp的左子树设为空,挂到最右边那个子节点上去
- temp = root
- root = root.left # 此时根结点被挂到子树上了,我们要变更根结点了,该操作不能放到 temp.left = None 后面,否则执行 temp.left = None 时 root.left 也会被置为空
- temp.left = None
- pre.right = temp
- else:
- res.append(root.val) # 如果当前节点已经是最左边的节点了,则可以输出它的值,并开始遍历右子树了
- root = root.right
- return res
-
-
- if __name__ == '__main__':
- # 创建一个二叉树
- tree = TreeNode(1)
- tree.left = TreeNode(2)
- tree.right = TreeNode(3)
- tree.left.left = TreeNode(4)
- tree.left.right = TreeNode(5)
- tree.right.left = TreeNode(6)
-
- # 执行中序遍历
- sol = Solution()
- print(sol.inorderTraversal(tree)) # [4, 2, 5, 1, 6, 3]
最近又看到 Morris 中序遍历的第二种解法(该方法最终不改变树的结构),提交结果很喜人,在这里分享一下代码:
- # Definition for a binary tree node.
- class TreeNode(object):
- def __init__(self, val=0, left=None, right=None):
- self.val = val
- self.left = left
- self.right = right
-
-
- class Solution(object):
- def inorderTraversal(self, root):
- res = []
- while root:
- if root.left:
- tmp = root.left
- while tmp.right and tmp.right != root:
- tmp = tmp.right
- if tmp.right is None:
- tmp.right = root
- root = root.left
- else:
- pre = root
- res.append(pre.val)
- tmp.right = None
- root = root.right
- else:
- pre = root
- res.append(pre.val)
- root = root.right
- return res
-
-
- if __name__ == '__main__':
-
- # 创建一个二叉树
- tree = TreeNode(3)
- tree.left = TreeNode(1)
- tree.right = TreeNode(4)
- tree.right.left = TreeNode(2)
-
- # 执行中序遍历
- sol = Solution()
- print(sol.inorderTraversal(tree)) # [1, 3, 2, 4]
逻辑图:
图例顺序:从左往右,从上往下
其中,pre的指向顺序就是中序遍历的节点顺序。
原理:
如果root已经是最左节点了,则输出root节点值;
如果root的左结点的右节点指向的就是root,那么则输出root节点值。
pre参数可以优化掉:
- class Solution(object):
- def inorderTraversal(self, root):
- res = []
- while root:
- if root.left:
- temp = root.left
- while temp.right and temp.right != root:
- temp = temp.right
- if not temp.right:
- temp.right = root
- root = root.left
- else: # temp.right == root 的情况
- res.append(root.val)
- temp.right = None
- root = root.right
- else:
- res.append(root.val)
- root = root.right
- return res
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。