1. 实现思路
(1)运用递归算法来实现
(2)运用栈的先进后出的思想来完成
2. 前序遍历
2.1 运用递归实现前序遍历
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if(root == null){
return result;
}
//根据递归获取左子树的值
List<Integer> left = preorderTraversal(root.left);
//根据递归获取右子树的值
List<Integer> right = preorderTraversal(root.right);
result.add(root.val);
result.addAll(left);
result.addAll(right);
return result;
}
}
2.2 使用栈来实现前序遍历
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if(root == null){
return result;
}
Stack<TreeNode> stack = new Stack();
stack.push(root);
while(!stack.isEmpty()){
//将根节点的值加入到数组
TreeNode current = stack.pop();
result.add(current.val);
//本段代码为加入左右孩子节点
//根据前序遍历,要先遍历左孩子节点,而栈是后进先出,所以先在栈中加入右孩子节点
if(current.right != null){
stack.push(current.right);
}
if(current.left != null){
stack.push(current.left);
}
}
return result;
}
3.中序遍历
3.1 运用递归实现中序遍历
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if(root == null){
return result;
}
List<Integer> left = inorderTraversal(root.left);
List<Integer> right = inorderTraversal(root.right);
result.addAll(left);
result.add(root.val);
result.addAll(right);
return result;
}
}
3.2 运用栈实现中序遍历
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if(root == null){
return result;
}
Stack<TreeNode> stack = new Stack();
TreeNode current = root;
//中序遍历的顺序为:左、根、右,我们需要先将左子树推进栈中
while(current != null || !stack.isEmpty()){
//推入左子树
while(current != null){
stack.push(current);
current = current.left;
}
current = stack.pop();
result.add(current.val);
//左、根都完成后加入右
current = current.right;
}
return result;
}
}
4.后序遍历
4.1使用递归实现后序遍历
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if(root == null){
return result;
}
List<Integer> left = postorderTraversal(root.left);
List<Integer> right = postorderTraversal(root.right);
result.addAll(left);
result.addAll(right);
result.add(root.val);
return result;
}
4.2 使用栈实现后续遍历
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if(root == null){
return result;
}
Stack<TreeNode> stack = new Stack();
stack.push(root);
while(!stack.isEmpty()){
TreeNode current = stack.peek();
//没有左右子节点则直接返回
if(current.left == null && current.right == null){
result.add(stack.pop().val);
}
//加入右孩子节点,加入后记得要把当节点右孩子置为null
if(current.right != null){
stack.push(current.right);
current.right = null;
}
//加入左孩子节点,加入后记得要把当节点左孩子置为null
if(current.left != null){
stack.push(current.left);
current.left = null;
}
}
return result;
}
}
5.总结
关于左右子树的遍历核心在于:(1)要明确不同遍历方式的遍历顺序。(2)明确递归的思想,如何通过递归实现对于左子树节点和右子树节点的获取。(3)要理解栈后进先出的思想,对于后遍历的节点要先进栈,先遍历的节点后进栈。