二叉树深度优先遍历和层次遍历
public class Basic {
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
// 二叉树的遍历有前中后三种深度优先遍历方法, 前中后指的是中间节点的处理顺序
// 递归遍历:递归遍历三要素
public void preOrderRecursion(TreeNode root) {
if (root == null) {
return;
}
System.out.println(root.val);
preOrderRecursion(root.left);
preOrderRecursion(root.right);
}
public void inorderRecursion(TreeNode root) {
if (root == null) {
return;
}
inorderRecursion(root.left);
System.out.println(root.val);
inorderRecursion(root.right);
}
public void postOrderRecursion(TreeNode root) {
if (root == null) {
return;
}
postOrderRecursion(root.left);
postOrderRecursion(root.right);
System.out.println(root.val);
}
// 迭代遍历
// 前序: root入栈-> 栈非空循环-> 访问栈顶元素(中)-> 右节点入栈(右入栈会先访问左节点,非空)-> 左节点入栈(后入栈先访问, 非空)
public void preOrder(TreeNode root) {
if (root == null) return;
Stack<TreeNode> stack = new Stack<>();
stack.add(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
System.out.println(node.val); // 中
if (node.right != null) stack.add(node.right);
if (node.left != null) stack.add(node.left);
}
}
// 中序: 重点记忆, root节点向左子树遍历到终点null所有节点压栈(此时左节点也是中间节点)->
// 弹栈访问-> 转向右节点-> 右节点为空时候继续弹栈访问不为空访问右节点
// 最终完成左中右的遍历顺序
public void inOrder(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.isEmpty()) {
if (root != null) {
stack.add(root);
root = root.left;
} else {
TreeNode node = stack.pop();
System.out.print(node.val);
root = node.right;
}
}
}
// 后序: 先序是中左右, 后序是左右中, 后序可以看作是中右左的倒序列, python是实现中使用两个栈, 第二个栈的作用就是倒序输入作用。
public void postOrder(TreeNode root) {
if (root == null) return;
Stack<TreeNode> stack = new Stack<>();
List<Integer> list = new ArrayList<>();
stack.add(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
list.add(node.val);
if (node.left != null) stack.add(node.left);
if (node.right != null) stack.add(node.right);
}
Collections.reverse(list);
}
// 层次遍历:迭代, 使用一个队列-> root入队列-> 队列中元素弹出将其左右节点依次入栈
public void levelOrder(TreeNode root) {
LinkedList<TreeNode> queue = new LinkedList<>();
if (root == null) return;
queue.add(root);
while (!queue.isEmpty()) {
int loop = queue.size(); // 将queue中一层元素全部弹出,就是设置将size作为循环次数
while (loop > 0) {
TreeNode node = queue.pop();
System.out.println(node.val);
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
loop--;
}
}
}
// 层次遍历:递归
}