基本思路:
二叉树的深度优先遍历(中序遍历)需要一个栈用于遍历,一个列表用于记录访问过的节点
- 1.将根节点压入栈中
- 2.1栈顶元素有左子节点且其左子节点不在列表当中,将其左子节点压入栈中
- 2.2.1如果栈顶元素没有左子节点或其左子节点在列表中,弹出栈顶元素并访问(还要将其加入到列表中)。
- 2.2.2如果弹出的节点有右子节点,将其右子节点压入栈
- 3.如果栈不为空,执行2
如上图所示,则采用当前思路遍历的顺序是D->B->E->H->A->F->C->G。
代码
public class DepthFirstSearch {
public static void depthFirstSearch(Node root) {
if (root == null) {
return;
}
Stack<Node> stack = new Stack<Node>();
// 用于记录访问过的节点
List<Node> list = new ArrayList<Node>();
stack.push(root);
while (!stack.isEmpty()) {
// 左子节点不为空且未访问过
Node left = stack.peek().left;
if (left != null && !list.contains(left)) {
stack.push(left);
} else {
Node curr = stack.pop();
// 访问当前节点
System.out.println(curr);
list.add(curr);// 记录
if (curr.right != null) {
stack.push(curr.right);
}
}
}
}
public static void main(String[] args) {
Node H = new Node("H");
Node B = new Node(new Node(null, null, "D"), new Node(null, H, "E"), "B");
Node C = new Node(new Node(null, null, "F"), new Node(null, null, "G"), "C");
Node A = new Node(B, C, "A");
depthFirstSearch(A);
}
}
/**
* 二叉树节点类
*
* @author Administrator
*
* @param <T>
*/
class Node<T> {
Node left;
Node right;
T value;
public Node() {
}
public Node(T value) {
this(null, null, value);// 正确的写法是使用this关键字表示构造方法
// ! 错误的写法new Node(null,null,value);
}
public Node(Node left, Node right, T value) {
this.left = left;
this.right = right;
this.value = value;
}
@Override
public String toString() {
return "Node [value=" + value + "]";
}
}