先一路走到 D ,一路上过来的节点都属第一次访问,不输出,然后访问 D 的左子树,发现为空,倒回来再走到 D ,此时D就是第二次访问,进行输出,然后再访问D的右子树,发现为空,再倒回到D。
D这个节访问完毕后,倒回到B节点,此时B是第二次访问,输出B,然后访问B的右子树。
E节点是第一次访问,左根右,继续往左走,走到G,继续访问G的左子树,发现为空,倒回去访问G,此时G是第二次访问,进行输出;再去访问G的右子树,节点H是第一次访问,继续往左走,H的左子树为空,倒回去走H此时H是第二次访问,进行输出。 4.此时我们已经输出了 D B G H,剩下的节点以次类推就行。 那么上面这颗二叉树的遍历代码应该如何去写呢?我们首相应该想到的是递归,因为二叉树就是一个天然的递归结构。
3.1自定义二叉树
public void build() {
//先将所有的节点值保存到node中
TreeNode node = new TreeNode<>('A');
TreeNode node1 = new TreeNode<>('B');
TreeNode node2 = new TreeNode<>('C');
TreeNode node3 = new TreeNode<>('D');
TreeNode node4 = new TreeNode<>('E');
TreeNode node5 = new TreeNode<>('F');
TreeNode node6 = new TreeNode<>('G');
TreeNode node7 = new TreeNode<>('H');
//根据上图连接二叉树
//A节点的左子树是B,也就是node1,下面的节点以此类推
node.left = node1;
node.right = node2;
node1.left = node3;
node1.right = node4;
node2.right = node5;
node4.left = node6;
node6.right = node7;
//根节点是A
root = node;
//自定义类型TreeNode类保存树的左右子树和节点值
private class TreeNode {
//当前结点的值
E val;
//左子树的根
TreeNode left;
//右子树的根
TreeNode right;
public TreeNode(E val) {
this.val = val;
}
}
}
public class TreeTest {
public static void main(String[] args) {
MyBinTree binTree = new MyBinTree();
binTree.build();
System.out.println("前序遍历:");
binTree.preOrder(binTree.root);
}
}
运行结果如下:
3.3 前序遍历(迭代)
public List preorderNoRecursion(TreeNode root) {
List ret = new ArrayList<>();
if (root == null) {
return ret;
}
Deque stack = new LinkedList<>();
stack.push(root);
while(!stack.isEmpty()) {
TreeNode node = stack.pop();
//添加根结点
ret.add((Character) node.val);
//因为栈是先进后出的,所以先添加右子树,后添加左子树
//下一次循环开始的时候,先添加到数组ret中的就是左子树的值了
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
return ret;
}
定义测试类:
public class TreeTest {
public static void main(String[] args) {
MyBinTree binTree = new MyBinTree();
binTree.build();
System.out.println("前序遍历:");
System.out.println(binTree.preorderNoRecursion(binTree.root));
}
}