二叉树的三种遍历方式
网上关于二叉树的三种遍历介绍地很详细,写这篇博客的目的是自己记录一下使用递归和非递归的方式实现这三种遍历方式的过程,防止之后大脑短路的时候难以找到资源。
前序遍历
// 递归实现前序遍历(中、左、右)
public static void preBL(Node root) {
if (root == null) {
return;
}
System.out.println(root.val);
preBL(root.left);
preBL(root.right);
}
// 非递归实现前序遍历
public static void unPreBL(Node root) {
Stack<Node> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
// 遍历完成,出栈
// 关键点在于每次出栈的时候只是出一个,所以右结点就放到了最后才遍历。
Node 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 midBL(Node root) {
if (root == null) {
return;
}
midBL(root.left);
System.out.println(root.val);
midBL(root.right);
}
// 非递归实现中序遍历(左、中、右)
public static void unMidBL(Node root) {
Stack<Node> stack = new Stack<>();
while (!stack.isEmpty() || root != null) {
// 判断是否扫到了最左边的结点
if (root != null) {
stack.push(root);
// 直至扫描到最左边的结点
root = root.left;
} else {
// 当扫描到最左边的结点的时候,出栈并打印当前结点
// 然后扫描最左结点的右子树
root = stack.pop();
System.out.println(root.val);
root = root.right;
}
}
}
后序遍历
// 递归实现后序遍历(左、右、中)
public static void aftBL(Node root) {
if (root == null) {
return;
}
aftBL(root.left);
aftBL(root.right);
System.out.println(root.val);
}
// 非递归实现后序遍历(左、右、中)
public static void UnAftBL(Node root) {
// 转化成为前序遍历,借助两个栈实现
Stack<Node> stack1 = new Stack<>();
Stack<Node> stack2 = new Stack<>();
stack1.push(root);
// 按照前序遍历的思想,只是不打印,而将结点压入第二个栈中
while (!stack1.isEmpty()) {
Node node = stack1.pop();
stack2.push(node);
if (node.left != null){
stack1.push(node.left);
}
if (node.right != null){
stack1.push(node.right);
}
}
// 此时遍历输出第二个栈的结点就是后序遍历。
while (!stack2.isEmpty()) {
System.out.println(stack2.pop().val);
}
}
}