给定一个二叉树的根节点 root ,返回它的 中序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[2,1]
示例 5:
输入:root = [1,null,2]
输出:[1,2]
方法一:递归 class Solution { List<Integer> a=new ArrayList<Integer>(); public List<Integer> inorderTraversal(TreeNode root) { if(root==null)return a; else{ inorderTraversal(root.left); a.add(root.val); inorderTraversal(root.right); } return a; } }
方法二:迭代 class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<Integer>(); Deque<TreeNode> stk = new LinkedList<TreeNode>();//双向队列存储节点 while (root != null || !stk.isEmpty()) { while (root != null) { stk.push(root); root = root.left; } root = stk.pop(); res.add(root.val); root = root.right; } return res; } }
方法三:Morris 中序遍历 class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<Integer>(); TreeNode predecessor = null; while (root != null) { if (root.left != null) { // predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止 predecessor = root.left; while (predecessor.right != null && predecessor.right != root) { predecessor = predecessor.right; } // 让 predecessor 的右指针指向 root,继续遍历左子树 if (predecessor.right == null) { predecessor.right = root; root = root.left; } // 说明左子树已经访问完了,我们需要断开链接 else { res.add(root.val); predecessor.right = null; root = root.right; } } // 如果没有左孩子,则直接访问右孩子 else { res.add(root.val); root = root.right; } } return res; } }
知识点:
写递归时可以创建一个公用属性,减少内存消耗。
ArrayList.add():将元素插入到指定位置的 arraylist 中
ArrayList.addAll():添加集合中的所有元素到 arraylist 中
Deque<TreeNode> stk = new LinkedList<TreeNode>();
LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
总结:
树最好使用递归解题。