给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3]
1
2
/
3
输出: [1,3,2]
中序遍历:二叉树遍历中,先遍历左子树,然后访问根节点,然后遍历右子树;
方法:递归
思路:每一个二叉树,都是由无数个子二叉树构成,从根节点开始递归,一直取左节点对应的二叉树,直到这个节点没有左分支,将这个值存入结果集,然后回溯到当前子二叉树的根节点,并且将这个值存入结果集,然后就是取右节点的值,右节点有可能有很多子二叉树,根据同理从该右节点的左子二叉树开始遍历,若没有子二叉树,那么就将这个点的值存入结果集,这样,回溯完成整个二叉树的遍历即可;
注意:详情可见百度百科;
/**
* 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) {
List<Integer> res = new ArrayList<>();
inorder(res,root);
return res;
}
//递归
private void inorder(List<Integer> res, TreeNode root) {
//中序遍历,就是先左节点,在根节点,在右节点;
//结束条件
if (root == null)
return;
//递归
else {
//递归遍历左树,直到最左边,拿节点的值
inorder(res,root.left);
res.add(root.val);
//递归遍历右树
inorder(res,root.right);//遍历右树时也是从左开始;
}
}
}
方法:迭代
思路:根据堆栈先进后出的原理,将整个二叉树按照递归的思路,从左子二叉树开始遍历,一次全部压入栈中,当左二叉树为null时,就开始往出拿,拿出来的就是最后存入的左节点(该节点没有左分叉),取到值存入结果集即可,当左节点取出后,下一步应该判断将该节点的有分叉是否由子二叉树,存在则按上述流程将该子二叉树压入栈,然后没有则说明为null,则直接依次往出取即可;
举个例子:
1
2
/
3
先将这个二叉树压入栈中,然后判断1这个节点左二叉树为null,则将这个值存到结果集,在判断该节点是否有右二叉树,是存在的,将这个2右二叉树压入栈,然后判断这个2右二叉树是否存在左二叉树,也存在,那么将3这个左二叉树压入栈,在继续判断,3没有左二叉树,将3取出存入结果集,然后判断3有没有右二叉树,也没有,那么就继续从栈里取出2这个子二叉树,将它的值存入结果集,在判断2是否有右子二叉树,也没用,那么继续从栈里面取,也没有了,说明迭代完成了,拿到了中序遍历,就是【1,3,2】;
/**
* 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) {
List<Integer> res = new ArrayList<>();
iterative(res,root);
return res;
}
//迭代
private void iterative(List<Integer> res, TreeNode root) {
//不断迭代,直到取完,根据堆栈先进后出,将一个个子二叉树存入堆栈然后按中序取值
if (root != null) {
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || root != null) {
//将左子树全部压入堆栈,直到root为null
if (root != null) {
stack.push(root);
root = root.left;
} else {//root == null,开始从stack里面取
root = stack.pop();
res.add(root.val);//将值存入
root = root.right;//将当前二叉树的右二叉树压进栈(然后从左开始拿)
}
}
}
}
}