二叉树的中序遍历
Posted treasury
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的中序遍历相关的知识,希望对你有一定的参考价值。
给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3]
1
2
/
3
输出: [1,3,2]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
题解1:
使用递归,左中右
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 class Solution { 11 List<Integer> list=new ArrayList<>(); 12 13 public List<Integer> inorderTraversal(TreeNode root) { 14 inorder(root); 15 return list; 16 17 } 18 public void inorder(TreeNode root){ 19 //递归算法 20 if(root==null) 21 return; 22 inorderTraversal(root.left); 23 list.add(root.val); 24 inorderTraversal(root.right); 25 } 26 }
时间复杂度 O(n) ,因为递归函数为Tn=2*T(n/2)+1
空间复杂度:最坏情况下需要空间O(n),平均情况为O(logn)。
题解2:
迭代法,基于栈的遍历(递归本身就是使用的栈,所以利用栈很自然)
1 public class Solution { 2 public List < Integer > inorderTraversal(TreeNode root) { 3 List < Integer > res = new ArrayList < > (); 4 Stack < TreeNode > stack = new Stack < > (); 5 TreeNode curr = root; 6 while (curr != null || !stack.isEmpty()) { 7 while (curr != null) { 8 stack.push(curr); 9 curr = curr.left; 10 } 11 curr = stack.pop(); 12 res.add(curr.val); 13 curr = curr.right; 14 } 15 return res; 16 } 17 }
时间复杂度 :O(n)
空间复杂度:O(n)
题解3:颜色标记法(一种通用且简明的方法)
该法优点:兼具栈迭代方法的高效,又像递归方法一样简洁易懂,更重要的是,这种方法对于前序、中序、后序遍历,能够写出完全一致的代码。
其核心思想如下:
使用颜色标记节点的状态,新节点为白色,已访问的节点为灰色。
如果遇到的节点为白色,则将其标记为灰色,然后将其右子节点、自身、左子节点依次入栈。
如果遇到的节点为灰色,则将节点的值输出。
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 class Solution { 11 12 class ColorNode { 13 TreeNode node; 14 String color; 15 16 public ColorNode(TreeNode node,String color){ 17 this.node = node; 18 this.color = color; 19 } 20 } 21 public List<Integer> inorderTraversal(TreeNode root) { 22 if(root == null) 23 return new ArrayList<Integer>(); 24 25 List<Integer> res = new ArrayList<>(); 26 Stack<ColorNode> stack = new Stack<>(); 27 stack.push(new ColorNode(root,"white")); 28 29 while(!stack.empty()){ 30 ColorNode cn = stack.pop(); 31 32 if(cn.color.equals("white")){ 33 if(cn.node.right != null) stack.push(new ColorNode(cn.node.right,"white")); 34 35 stack.push(new ColorNode(cn.node,"gray")); 36 37 if(cn.node.left != null)stack.push(new ColorNode(cn.node.left,"white")); 38 }else{ 39 res.add(cn.node.val); 40 } 41 } 42 43 return res; 44 } 45 }
这种方法比较通用,简单好记
时间复杂度 :O(n)
空间复杂度:O(n)
题解4:莫里斯遍历(了解)
若current没有左子节点
a. 将current添加到输出
b. 进入右子树,亦即, current = current.right
否则
a. 在current的左子树中,令current成为最右侧节点的右子节点
b. 进入左子树,亦即,current = current.left
class Solution { public List < Integer > inorderTraversal(TreeNode root) { List < Integer > res = new ArrayList < > (); TreeNode curr = root; TreeNode pre; while (curr != null) { if (curr.left == null) { res.add(curr.val); curr = curr.right; // move to next right node } else { // has a left subtree pre = curr.left; while (pre.right != null) { // find rightmost pre = pre.right; } pre.right = curr; // put cur after the pre node TreeNode temp = curr; // store cur node curr = curr.left; // move cur to the top of the new tree temp.left = null; // original cur left be null, avoid infinite loops } } return res; } }
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal
以上是关于二叉树的中序遍历的主要内容,如果未能解决你的问题,请参考以下文章