二叉树的中序遍历

给定一个二叉树,返回它的中序 遍历。

示例:

输入: [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


__EOF__

本文作者程序员小宇
本文链接https://www.cnblogs.com/treasury/p/12600426.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   程序员小宇  阅读(554)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示