2020年9月14日 二叉树的中序遍历inorderTraversal
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
LinkedList<Integer> res=new LinkedList<>();
if (root==null)
return res;
res.addAll(0, inorderTraversal(root.left));
res.add(root.val);
res.addAll(inorderTraversal(root.right) );
return res;
}
}
解题思路:
先使用递归尝试完成,理解一下这道题的思路:
递归的思路很简单,递归每一个节点时都是先递归左子树,再输出当前值,最后递归右子树的流程。
public List<Integer> inorderTraversal(TreeNode root) {
LinkedList<Integer> res=new LinkedList<>();
if (root==null)
return res;
res.addAll(0, inorderTraversal(root.left));
res.add(root.val);
res.addAll(inorderTraversal(root.right) );
return res;
}
迭代如何完成呢?
迭代是使用手动规定的一个栈来模拟递归的过程,那么问题就在于如何模拟呢?
那么我们应该先搞清楚递归的流程再来模拟。
递归实际上第一个放入结果集的节点是哪一个?应该是最左边的那一个叶子节点。
我们可以这么设计逻辑:
如果当前栈顶的节点存在左子节点,那么把这个子节点放入栈顶。并且删除掉自己的左节点,避免重复。
如果当前栈顶的节点不存在左子节点,那就把当前值加入结果集。然后将右子节点放入栈顶。
我们每一次处理都是从栈顶取出节点来处理。处理结束的标志就是栈中没有节点了。
public List<Integer> inorderTraversal2(TreeNode root) {
LinkedList<Integer> res=new LinkedList<>();
if (root==null)
return res;
LinkedList<TreeNode> list=new LinkedList<>();
list.add(root);
while (list.size()!=0){
TreeNode first = list.getFirst();
if (first.left!=null){
list.add(0,first.left);
first.left=null;
}
else {
res.add(first.val);
list.removeFirst();
if (first.right!=null)
list.add(0,first.right );
}
}
return res;
}
其实迭代时间复杂度并不是比递归要低,而是因为我在递归的过程中构建了很多次的链表,这一点非常消耗时间。