10种二叉树的遍历方法
今天敲了一下数据结构课上学的二叉树的遍历方法,又在网上看了一些大牛们写的好方法,在这里做一个小小的总结。才疏学浅,若有错误欢迎大家多多指出,一定虚心接受。
文章目录
首先附上表示二叉树节点的类。
/*
* 节点类
*/
public static class Node {
private int value;
private Node left;
private Node right;
public Node(int val) {
value = val;
}
}
一、递归遍历
使用递归地方式来遍历二叉树,本质上是计算机替我们做了压栈弹栈的工作。使用递归的时间复杂度会很高,但是书写起来十分简单。
1.先序遍历
递归的先序遍历思路:若二叉树非空,则依次:
⑴ 访问根结点;
⑵ 遍历左子树;
⑶ 遍历右子树。
public static void preOrderRecur(Node head) {
if (head == null) {
return;
}
System.out.print(head.value + " ");
preOrderRecur(head.left);
preOrderRecur(head.right);
}
2.中序遍历
递归的中序遍历思路:若二叉树非空,则依次:
⑴遍历左子树;
⑵访问根结点;
⑶遍历右子树。
public static void inOrderRecur(Node head) {
if (head == null) {
return;
}
inOrderRecur(head.left);
System.out.print(head.value + " ");
inOrderRecur(head.right);
}
3.后序遍历
递归的后序遍历思路:若二叉树非空,则依次:
⑴遍历左子树;
⑵遍历右子树;
⑶访问根节点。
public static void posOrderRecur(Node head) {
if (head == null) {
return;
}
posOrderRecur(head.left);
posOrderRecur(head.right);
System.out.print(head.value + " ");
}
二、统一简单好记的非递归遍历
主要思路:模拟电脑的压栈过程,用一个布尔值标记某个节点是否已经访问到了。访问时将父亲节点和子节点按顺序添加进栈中,再不停从栈中取出节点。 如果已经访问过了等再次访问时就可以直接输出。
这是在简书上看到一个很厉害的博主写的,我把他写成了Java版本,证明可以直接看原博主写的文章。附上 传送门,下面直接上代码,有注释。
1.先序遍历
public static class nodeAndState {
// 用来记录某一个节点是否被访问过
private Node node;
private boolean isVisited;
public nodeAndState(Node node, boolean isVisited) {
this.node = node;
this.isVisited = isVisited;
}
}
public static void preOrderUnrecurEasy(Node head) {
if (head == null) {
return;
}
Stack<nodeAndState> TonyStack = new Stack<nodeAndState>(); // 访问栈
TonyStack.push(new nodeAndState(head, false));
while (!TonyStack.isEmpty()) {
nodeAndState cur = TonyStack.