二叉树的三种遍历方式(Java实现)
144. 二叉树的前序遍历
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[1,2]
示例 5:
输入:root = [1,null,2]
输出:[1,2]
思路1(递归解法)
递归解法比较简单,也很常规,就不再多说思路了
public List<Integer> preorderTraversal(TreeNode root) {
//新建一个链表
List<Integer> list = new ArrayList<Integer>();
if(root == null){
return list;
}
preOrder(root, list);
return list;
}
public void preOrder(TreeNode root, List<Integer> list){
list.add(root.val);
if(root.left != null){
preOrder(root.left, list);
}
if(root.right != null){
preOrder(root.right, list);
}
}
思路2 (利用栈进行遍历)
步骤:
- 新建一个栈stack
- 将root放入栈中
- pop栈顶,将pop元素的右结点和左结点入栈
- 重复上述操作直到stack空
代码:
List<Integer> list = new ArrayList<Integer>();
if(root == null){
return list;
}
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
while(!stack.isEmpty){
TreeNode t = stack.pop();
list.add(t.val);
if(t.right != null){
stack.push(t.right);
}
if(t.left != null){
stack.push(t.left);
}
}
return list;
思路3(迭代法遍历模板)
步骤:
- 创建一个栈stack和一个数组list
- 循环判断栈或者root结点是否均为空,如果满足则结束,否则进入步骤3
- 判断root结点是否为空,如果不为空则将root.val加入到list中,并令root入栈,并令root = root.left
- 令root = stack.pop().right,跳转至步骤2
//创建一个数组list
List<Integer> list = new ArrayList<Integer>();
if(root == null){
return list;
}
//创建一个栈stack
Stack<TreeNode> stack = new Stack<TreeNode>();
//循环判断stack或者root均为空
while(!stack.isEmpty() || root != null){
while(root != null){
list.add(root.val);
stack.push(root);
root = root.left;
}
root = stack.pop().right;
}
return list;
94. 二叉树的中序遍历
给定一个二叉树的根节点 root
,返回 它的 中序 遍历 。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
思路1(递归解法)
递归法比较简单
public void infixOrder(TreeNode root, List<Integer>list){
if(root == null){
return;
}
infixOrder(root.left, list);
list.add(root.val);
infixOrder(root.right, list);
}
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<Integer>();
infixOrder(root, list);
return list;
}
思路2 (迭代解法)
步骤:
- 创建一个栈stack和一个队列list
- 循环判断stack是否为空并且root为null,如果满足则结束循环,否则进入步骤3
- 循环判断root.left是否为空,若不为空则将结点root入栈,并且令root = root.left,即将左子结点全部入栈,当root为叶子结点时,结束循环
- 令root = stack.pop(),list.add(root.val),再令root = root.right, 返回步骤2
List<Integer> list = new ArrayList<Integer>();
Stack<TreeNode> stack = new Stack<TreeNode>();
while(!stack.isEmpty() || root != null){
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
list.add(root.val);
root = root.right;
}
return list;
145. 二叉树的后序遍历
给你一棵二叉树的根节点 root
,返回其节点值的 后序遍历 。
示例 1:
输入:root = [1,null,2,3]
输出:[3,2,1]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
思路1(递归方法)
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<Integer>();
postOrder(root, list);
return list;
}
public void postOrder(TreeNode root, List<Integer> list){
if(root == null){
return;
}
postOrder(root.left, list);
postOrder(root.right, list);
list.add(root.val);
}
思路2 (迭代模板)
利用栈和一个辅助指针实现,步骤:
- 创建一个栈stack和一个数组list,并初始化辅助指针pre
- 循环判断stack为空并且root为空,若都满足则程序结束,否则进入步骤3
- 循环将root的左子节点压入栈,再令root = root.left,直到root指向null
- 令root = stack.pop()
- 如果结点的右子树为空或者右子树与pre相同,则将root存放的值加入到list中list.add(root.val),令pre指向root结点pre = root,否则将root压回到栈中。完成上述判断后,让root指向空root = null
- 返回步骤2直至程序结束,返回list
public List<Integer> postorderTraversal(TreeNode root) {
//创建一个栈stack
Stack<TreeNode> stack = new Stack<TreeNode>();
//创建一个数组list
List<Integer> list = new ArrayList<Integer>();
//初始化辅助指针pre
TreeNode pre;
//循环判断栈stack和root是否均为空
while(!stack.isEmpty() || root != null){
//循环将左子节点压入栈
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
if(root.right == null || root.right != pre){
list.add(root.val);
pre = root;
}else{
stack.push(root);
root = root.right;
}
root = null;
}
return list;
}