题目描述
给定一个二叉树,返回它的中序 遍历
样例
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,3,2]
思路分析
方法一:递归,按照中序遍历“左根右”的顺序,依次遍历,递归即可
方法二:和先序类似,非递归实现,由根节点向左遍历(过程中并不添加),直到叶子节点,随后pop操作相当于返回上一节点,再遍历右子树部分即可
方法三:非递归,不用栈,构造两指针
思路如下:(参考了这个帖子https://blog.csdn.net/cyuyanenen/article/details/51620559)
1. 如果当前节点的左孩子为空,则输出当前节点并将当前节点的右孩子作为“新的当前节点”。
2.如果当前节点的左孩子不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点。
- 如果前驱节点的右孩子为空,那么将当前节点设置为前驱节点的右孩子。把当前节点的左孩子设置为”新的当前节点“。
- 如果前驱节点的右孩子为当前节点,将前驱节点的右孩子重新设为空(即恢复树的形状)。然后输出当前节点,并将当前节点的右孩子设置为”新的当前节点“。
放图
代码及结果
方法一:
public List<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (root == null) {
return list;
}
return inorderTraversal(root, list);
}
public List<Integer> inorderTraversal(TreeNode root,List<Integer> list) {
if (root != null) {
if (root.left != null) {
inorderTraversal(root.left, list);
}
list.add(root.val);
if (root.right != null) {
inorderTraversal(root.right, list);
}
}
return list;
}
结果
方法二:
public List<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (root == null) {
return list;
}
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode temp = root;
while (!stack.isEmpty() || temp!=null) {
while (temp!=null) {
stack.push(temp);
temp = temp.left;
}
temp = stack.pop();
list.add(temp.val);
temp = temp.right;
}
return list;
}
方法三:
//方法三 不用栈
public List<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
TreeNode cur = root;
TreeNode pre = null;
while (cur != null) {
if (cur.left == null) {
list.add(cur.val);
cur = cur.right;
}
else {
pre = cur.left;
while (pre.right != null && pre.right != cur) {
pre = pre.right;
}
if (pre.right == null) {
pre.right = cur;
cur = cur.left;
}
else {
pre.right = null;
list.add(cur.val);
cur = cur.right;
}
}
}
return list;
}
结果