算法17-18二叉树
递归遍历
// 递归序的解释
// 用递归实现二叉树的三序遍历
public class BinaryTreeTraversalRecursion {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int v) {
val = v;
}
}
// 递归基本样子,用来理解递归序
public static void f(TreeNode head) {
if (head == null) {
return;
}
// 1
f(head.left);
// 2
f(head.right);
// 3
}
// 先序打印所有节点,递归版
public static void preOrder(TreeNode head) {
if (head == null) {
return;
}
System.out.print(head.val + " ");
preOrder(head.left);
preOrder(head.right);
}
// 中序打印所有节点,递归版
public static void inOrder(TreeNode head) {
if (head == null) {
return;
}
inOrder(head.left);
System.out.print(head.val + " ");
inOrder(head.right);
}
// 后序打印所有节点,递归版
public static void posOrder(TreeNode head) {
if (head == null) {
return;
}
posOrder(head.left);
posOrder(head.right);
System.out.print(head.val + " ");
}
非递归,用栈实现遍历
public class BinaryTreeTraversalIteration {//二叉树定义
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int v) {
val = v;
}
}
先序遍历-栈
// 先序打印所有节点,非递归版
public static void preOrder(TreeNode head) {
if (head != null) {
Stack<TreeNode> stack = new Stack<>();
stack.push(head);
while (!stack.isEmpty()) {
head = stack.pop();
System.out.print(head.val + " ");
if (head.right != null) {
stack.push(head.right);
}
if (head.left != null) {
stack.push(head.left);
}
}
System.out.println();
}
}
中序遍历-栈
// 中序打印所有节点,非递归版
public static void inO rder(TreeNode head) {
if (head != null) {
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || head != null) {
if (head != null) {//一直找到最左的节点
stack.push(head);
head = head.left;
} else {
head = stack.pop();
System.out.print(head.val + " ");
head = head.right;
}
}
System.out.println();
}
}
后序遍历-双栈
后续遍历是左右中,反过来就是中右左,双栈是用collect栈收集中右左顺序,然后利用栈先进后出的特性,输出为左右中
// 后序打印所有节点,非递归版
// 这是用两个栈的方法
public static void posOrderTwoStacks(TreeNode head) {
if (head != null) {
Stack<TreeNode> stack = new Stack<>();
Stack<TreeNode> collect = new Stack<>();
stack.push(head);
while (!stack.isEmpty()) {//中右左,跟先序遍历-栈很像
head = stack.pop();
collect.push(head);
if (head.left != null) {
stack.push(head.left);
}
if (head.right != null) {
stack.push(head.right);
}
}
while (!collect.isEmpty()) {
System.out.print(collect.pop().val + " ");
}
System.out.println();
}
}
后序遍历-单栈
挺难想的,看不懂了就再去看视频吧
运用的h很巧妙
// 这是用一个栈的方法
public static void posOrderOneStack(TreeNode h) {
if (h != null) {
Stack<TreeNode> stack = new Stack<>();
stack.push(h);
// 如果始终没有打印过节点,h就一直是头节点
// 一旦打印过节点,h就变成打印节点
// 之后h的含义 : 上一次打印的节点
while (!stack.isEmpty()) {
TreeNode cur = stack.peek();
if (cur.left != null && h != cur.left && h != cur.right) {//左树优先级最高
// 有左树且左树没处理过
stack.push(cur.left);
} else if (cur.right != null && h != cur.right) {//其次为右树
// 有右树且右树没处理过
stack.push(cur.right);
} else {
// 左树、右树 没有 或者 都处理过了
System.out.print(cur.val + " ");
h = stack.pop();
}
}
System.out.println();
}
}