一、二叉树的前序遍历
1、递归实现1:Traverse
public List<Integer> preorderTraversal(TreeNode root) {
// write your code here
List<Integer> list = new ArrayList<>();
preorderTraversal(root , list);
return list;
}
public void preorderTraversal(TreeNode root , List<Integer> list){
if(root == null)
return;
list.add(root.val);
preorderTraversal(root.left , list);
preorderTraversal(root.right , list);
}
2、递归实现2:Divide & Conquer
/**
* 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: Preorder in ArrayList which contains node values.
*/
public List<Integer> preorderTraversal(TreeNode root) {
// write your code here
List<Integer> list = new ArrayList<>();
if(root == null)
return list;
//Divide
List<Integer> left = preorderTraversal(root.left);
List<Integer> right = preorderTraversal(root.right);
//Conquer
list.add(root.val);
list.addAll(left);
list.addAll(right);
return list;
}
}
3、非递归实现1
-
利用栈实现循环先序遍历二叉树
-
* 这种实现类似于图的深度优先遍历(DFS)
-
* 维护一个栈,将根节点入栈,然后只要栈不为空,出栈并访问,接着依次将访问节点的右节点、左节点入栈。
-
* 这种方式应该是对先序遍历的一种特殊实现(看上去简单明了),但是不具备很好的扩展性,在中序和后序方式中不适用
public List<Integer> preorderTraversal(TreeNode root) {
// write your code here
List<Integer> list = new ArrayList<>();
if(root == null)
return list;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node = stack.pop();
list.add(node.val);
//注意这里先压右栈,再压左栈,与前序遍历相反
if(node.right != null)
stack.push(node.right);
if(node.left != null)
stack.push(node.left);
}
return list;
}
4、非递归实现2
* 利用栈模拟递归过程实现循环先序遍历二叉树
* 这种方式具备扩展性,它模拟递归的过程,将左子树点不断的压入栈,直到null,然后处理栈顶节点的右子树
/**
* 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: Preorder in ArrayList which contains node values.
*/
public List<Integer> preorderTraversal(TreeNode root) {
// write your code here
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while(root != null || !stack.isEmpty()){
//将二叉树左半部分先访问再入栈
while(root != null){
list.add(root.val);
stack.push(root);
root = root.left;
}
root = stack.pop();
root = root.right;//如果是null,出栈并处理右子树
}
return list;
}
}
二、二叉树的中序遍历
1、递归实现1:Traverse
public List<Integer> inorderTraversal(TreeNode root) {
// write your code here
List<Integer> list = new ArrayList<>();
inorderTraversal(root , list);
return list;
}
public void inorderTraversal(TreeNode root , List<Integer> list){
if(root == null)
return;
inorderTraversal(root.left , list);
list.add(root.val);
inorderTraversal(root.right , list);
}
2、递归实现2:Divide & Conquer
/**
* 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
List<Integer> list = new ArrayList<>();
if(root == null)
return list;
List<Integer> left = inorderTraversal(root.left);
List<Integer> right = inorderTraversal(root.right);
list.addAll(left);
list.add(root.val);
list.addAll(right);
return list;
}
}
3、非递归实现
-
利用栈模拟递归过程实现循环中序遍历二叉树
-
* 思想和二叉树前序遍历非递归实现2相同,只是访问的时间是在左子树都处理完直到null的时候出栈并访问。
/**
* 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
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while(root != null || !stack.isEmpty()){
//将二叉树左半部分压栈
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
list.add(root.val);
root = root.right;//如果是null,出栈并处理右子树
}
return list;
}
}
三、二叉树的后序遍历
1、递归实现1:Traverse
/**
* 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: Postorder in ArrayList which contains node values.
*/
public List<Integer> postorderTraversal(TreeNode root) {
// write your code here
List<Integer> list = new ArrayList<>();
postorderTraversal(root , list);
return list;
}
private void postorderTraversal(TreeNode root , List<Integer> list){
if(root == null)
return;
postorderTraversal(root.left , list);
postorderTraversal(root.right , list);
list.add(root.val);
}
}
2、递归实现2:Divide & Conquer
/**
* 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: Postorder in ArrayList which contains node values.
*/
public List<Integer> postorderTraversal(TreeNode root) {
// write your code here
List<Integer> list = new ArrayList<>();
if(root == null)
return list;
List<Integer> left = postorderTraversal(root.left);
List<Integer> right = postorderTraversal(root.right);
list.addAll(left);
list.addAll(right);
list.add(root.val);
return list;
}
}
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: Postorder in ArrayList which contains node values.
*/
public List<Integer> postorderTraversal(TreeNode root) {
// write your code here
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.isEmpty()) {
//将二叉树右半部分先访问再入栈
while (root != null) {
res.add(root.val);
stack.push(root);
root = root.right;
}
root = stack.pop();
root = root.left;
}
Collections.reverse(res);
return res;
}
}