版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lighthear/article/details/80033908
Description
Solution
算法思路:
- 遍历法(递归)
- 分治法(递归)
- 非递归法实现中序遍历的通用版本(非递归)
利用 stack 进行 Binary Tree Iterator。
- stack 中保存一路走到当前节点的路径中所有的节点。
- stack.peek() 一直指向 iterator 指向的当前节点,存入result中。
- hasNext() 只需要判断 stack 是否为空。
- 遍历时如果栈不为空,则返回 stack.peek() 的值,存入result中,并将 iterator 挪到下一个点,对 stack 进行相应的变化。
挪到下一个点的算法如下:
- 如果当前点存在右子树,那么就是右子树中“一路向西”最左边的那个点。
- 如果当前点不存在右子树,则是走到当前点的路径中,第一个左拐的点。
1. 遍历法(递归)
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/*
* @param root: A Tree
* @return: Inorder in ArrayList which contains node values.
*/
public List<Integer> inorderTraversal(TreeNode root) {
// write your code here
//Version 1: Traverse 遍历
List<Integer> result = new ArrayList<>();
traverse(root, result);
return result;
}
//1. 递归的定义
//把以root为根的所有inorder加入result里面
private void traverse(TreeNode root, List<Integer> result) {
//3. 递归的出口
if (root == null) {
return;
}
//2. 递归的拆解
traverse(root.left, result); //左
result.add(root.val); //根
traverse(root.right, result); //右
}
}
2. 分治法(递归)
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/*
* @param root: A Tree
* @return: Inorder in ArrayList which contains node values.
*/
public List<Integer> inorderTraversal(TreeNode root) {
// write your code here
//Version 2: Divide & conquer 分治算法
List<Integer> result = new ArrayList<>();
if (root == null) {
return result;
}
//Divide
List<Integer> left = inorderTraversal(root.left);
List<Integer> right = inorderTraversal(root.right);
//conquer
result.addAll(left);
result.add(root.val);
result.addAll(right);
return result;
}
}
3. 非递归法实现中序遍历的通用版本(非递归)
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/*
* @param root: A Tree
* @return: Inorder in ArrayList which contains node values.
*/
public List<Integer> inorderTraversal(TreeNode root) {
// write your code here
// Version 3 :通用的非递归实现中序遍历
Stack<TreeNode> stack = new Stack<>();
List<Integer> result = new ArrayList<>();
//一直往左边走,找到最左边的节点,并将路径上的点都入栈
while (root != null) {
stack.push(root);
root = root.left;
}
while (!stack.isEmpty()) {
TreeNode node = stack.peek();
result.add(node.val);
//调整栈的结构,找到下一个点
//2. 如果当前点不存在右子树,则是走到当前点的路径中,第一个左拐的点
//就是原路返回(stack.pop()),找到第一个左拐的点
//相当于左子树遍历完了,该遍历中间和右边了
if (node.right == null) {
node = stack.pop();
while (!stack.isEmpty() && stack.peek().right == node) {
node = stack.pop();
}
} else {
//1. 如果当前点存在右子树,那么就是右子树中“一路向左”最左边的那个点
//就是先向右走一步,然后一直向左走到头的那个点
node = node.right;
while (node != null) {
stack.push(node);
node = node.left;
}
}
}
return result;
}
}