二叉树
1、二叉树的递归遍历【LC 144 145 94题】
递归序
按照如下函数,遍历完每个节点都会经过三次。
以下图为例:首先经过recursion(2)->recursion(1)->recursion(1.left)【null 返回】->recursion(1)
->recursion(1.right)【null 返回】->recursion(1)->recursion(2)【返回】
->recursion(3)->recursion(3.left)【null 返回】->recursion(3)
->recursion(3.right)【null 返回】->recursion(3)->recursion(2)【最终返回,方法执行完】
public void recursion(TreeNode head){
if (head==null) return;
// 1
recursion(head.left);
// 2
recursion(head.right);
// 3
}
先序、中序、后序都可以从递归序中来
- 先序遍历【根左右】
在第一次来到节点的时候,打印
public void recursion(TreeNode head){
if (head==null) return;
System.out.println(head.val);
recursion(head.left);
// 2
recursion(head.right);
// 3
}
- 中序遍历【左根右】
在第二次来到节点的时候,打印
public void recursion(TreeNode head){
if (head==null) return;
// 1
recursion(head.left);
System.out.println(head.val);
recursion(head.right);
// 3
}
- 后序遍历【左右根】
在第三次回到节点的时候,打印
public void recursion(TreeNode head){
if (head==null) return;
// 1
recursion(head.left);
// 2
recursion(head.right);
System.out.println(head.val);
}
2、二叉树的非递归遍历【LC 144 145 94题】
任何递归函数都可以改成非递归函数。【利用栈先进后出的特性】
- 先序遍历【根左右】
压头节点弹出并打印,接着如果右节点存在先push右节点,如果左节点存在再push左节点。
public static void preOrder(TreeNode head){ //根左右
Stack<TreeNode> stack=new Stack<>();
stack.push(head);
while (!stack.isEmpty()){
TreeNode node=stack.pop();
System.out.println(node.val);
if (node.right!=null) stack.push(node.right);
if (node.left!=null) stack.push(node.left);
}
}
- 后序遍历【左右根】
在先序的基础上,换成【根右左】,再逆序打印,得出后序遍历。
public static void postOrder(TreeNode head){ //左右根
Stack<TreeNode> stack=new Stack<>();
Stack<Integer> tempstack=new Stack<>();
stack.push(head);
while (!stack.isEmpty()){
TreeNode node=stack.pop();
tempstack.add(node.val);
if (node.left!=null) stack.push(node.left);
if (node.right!=null) stack.push(node.right);
}
while (!tempstack.isEmpty()){
System.out.println(tempstack.pop());
}
}
- 中序遍历【左根右】
沿着左侧一直往下,没有左节点之后,弹出并输出,push右节点。对右节点进行同样的操作。
public static void inOrder(TreeNode head){ //左根右
Stack<TreeNode> stack=new Stack<>();
if (head==null) return;
while (!stack.isEmpty() || head!=null){
if (head!=null){
stack.push(head);
head=head.left;
}else{
head=stack.pop();
System.out.println(head.val);
head=head.right;
}
}
}
3、二叉树的层序遍历【LC 102题】
层序遍历用队列。
记录一下上一层一共有多少节点。对每个节点 进行左右子树的遍历。
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res=new ArrayList<>();
if (root==null) return res;
Queue<TreeNode> queue=new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()){
int size=queue.size(); //记录一下上一层一共有多少节点
ArrayList<Integer> list=new ArrayList<>();
for (int i = 0; i < size; i++) {
//对每个节点 进行左右子树的遍历
TreeNode temp=queue.poll();
list.add(temp.val);
if (temp.left!=null) queue.add(temp.left);
if (temp.right!=null) queue.add(temp.right);
}
res.add(list);
}
return res;
}