二叉树的前序、中序、后序遍历(递归版)

 

二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的。

1、二叉树的遍历方法

对于二叉树,有深度遍历和广度遍历,深度遍历有前序、中序以及后序三种遍历方法,广度遍历即我们平常所说的层次遍历。

因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁,而对于广度遍历来说,需要其他数据结构的支撑,比如堆。所以,对于一段代码来说,可读性有时候要比代码本身的效率要重要的多。

所谓前序,中序,后续遍历命名的由来是我们访问二叉树,根节点的顺序。前序遍历就是优先访问根节点,中序遍历是第二个访问根节点,后续遍历就是访问完左右节点之后,最后访问根节点。

注意访问二字。访问和获取是两个不同的概念,我们可以获取一个节点,但是不访问他。对应在计算机里的概念是,获取一个节点表示将他入栈,访问一个节点是他处于栈顶,我们即将让他出栈。

2、前序遍历(先序遍历)

前序遍历,就是优先访问根节点,然后访问左子节点,最后访问右子节点。说简单点就是:根左右。

直接上代码:

 1 public class TreeNode<N> implements Serializable {
 2 
 3     private N val;
 4 
 5     private TreeNode<N> left;
 6 
 7     private TreeNode<N> right;
 8 
 9     public TreeNode() {
10     }
11 
12     public TreeNode(N val) {
13         this.val = val;
14     }
15 
16     public TreeNode(N val, N leftVal, N rightVal) {
17         this.val = val;
18         this.left = new TreeNode<>(leftVal);
19         this.right = new TreeNode<>(rightVal);
20     }
21 
22     public N getVal() {
23         return val;
24     }
25 
26     public void setVal(N val) {
27         this.val = val;
28     }
29 
30     public TreeNode<N> getLeft() {
31         return left;
32     }
33 
34     public void setLeft(N left) {
35         this.left = new TreeNode<>(left);
36     }
37 
38     public TreeNode<N> getRight() {
39         return right;
40     }
41 
42     public void setRight(N right) {
43         this.right = new TreeNode<>(right);
44     }
45 }
46 
47 
48 public class treeTest {
49 
50     public static void main(String[] args) {
51         Queue<TreeNode<Integer>> queue = new LinkedList<>();
52         TreeNode<Integer> root = new TreeNode<>(0);
53         root.setLeft(1);
54         root.setRight(2);
55         root.getLeft().setLeft(3);
56         root.getLeft().setRight(4);
57         root.getRight().setLeft(5);
58         root.getRight().setRight(6);
59         System.out.println("   " + root.getVal());
60         System.out.println("  /  \\");
61         System.out.println(" " + root.getLeft().getVal() + "    " + root.getRight().getVal());
62         System.out.println("/ \\  / \\");
63         System.out.println(root.getLeft().getLeft().getVal() + " " +  root.getLeft().getRight().getVal() + "  "
64                 + root.getRight().getLeft().getVal() + "  " + root.getRight().getRight().getVal());
65 
66 
67 
68         List<Integer> qianXu = qian(root);
69         System.out.println(qianXu);
70     }
71 
72     private static List<Integer> qian(TreeNode<Integer> root) {
73         List<Integer> resut = new ArrayList<>();
74 
75         if(null == root) return resut;
76 
77         resut.add(root.getVal());
78         resut.addAll(qian(root.getLeft()));
79         resut.addAll(qian(root.getRight()));
80 
81         return resut;
82     }
83 }
前序遍历

输出结果:

3、中序遍历

中序遍历,就是优先访问左子节点,然后访问根节点,最后访问右子节点。说简单点就是:左根右。

示例代码:

 1 public class TreeNode<N> implements Serializable {
 2 
 3     private N val;
 4 
 5     private TreeNode<N> left;
 6 
 7     private TreeNode<N> right;
 8 
 9     public TreeNode() {
10     }
11 
12     public TreeNode(N val) {
13         this.val = val;
14     }
15 
16     public TreeNode(N val, N leftVal, N rightVal) {
17         this.val = val;
18         this.left = new TreeNode<>(leftVal);
19         this.right = new TreeNode<>(rightVal);
20     }
21 
22     public N getVal() {
23         return val;
24     }
25 
26     public void setVal(N val) {
27         this.val = val;
28     }
29 
30     public TreeNode<N> getLeft() {
31         return left;
32     }
33 
34     public void setLeft(N left) {
35         this.left = new TreeNode<>(left);
36     }
37 
38     public TreeNode<N> getRight() {
39         return right;
40     }
41 
42     public void setRight(N right) {
43         this.right = new TreeNode<>(right);
44     }
45 }
46 
47 
48 
49 public class treeTest {
50 
51     public static void main(String[] args) {
52         Queue<TreeNode<Integer>> queue = new LinkedList<>();
53         TreeNode<Integer> root = new TreeNode<>(0);
54         root.setLeft(1);
55         root.setRight(2);
56         root.getLeft().setLeft(3);
57         root.getLeft().setRight(4);
58         root.getRight().setLeft(5);
59         root.getRight().setRight(6);
60         System.out.println("   " + root.getVal());
61         System.out.println("  /  \\");
62         System.out.println(" " + root.getLeft().getVal() + "    " + root.getRight().getVal());
63         System.out.println("/ \\  / \\");
64         System.out.println(root.getLeft().getLeft().getVal() + " " +  root.getLeft().getRight().getVal() + "  "
65                 + root.getRight().getLeft().getVal() + "  " + root.getRight().getRight().getVal());
66 
67         List<Integer> zhongXu = zhong(root);
68         System.out.println(zhongXu);
69     }
70 
71     private static List<Integer> zhong(TreeNode<Integer> root) {
72         List<Integer> resut = new ArrayList<>();
73 
74         if(null == root) return resut;
75 
76         resut.addAll(zhong(root.getLeft()));
77         resut.add(root.getVal());
78         resut.addAll(zhong(root.getRight()));
79 
80         return resut;
81     }
82 }
中序遍历

输出结果:

4、后序遍历

后序遍历,就是优先访问左子节点,然后访问右子节点,最后访问根节点。说简单点就是:左右根。

示例代码:

 1 public class TreeNode<N> implements Serializable {
 2 
 3     private N val;
 4 
 5     private TreeNode<N> left;
 6 
 7     private TreeNode<N> right;
 8 
 9     public TreeNode() {
10     }
11 
12     public TreeNode(N val) {
13         this.val = val;
14     }
15 
16     public TreeNode(N val, N leftVal, N rightVal) {
17         this.val = val;
18         this.left = new TreeNode<>(leftVal);
19         this.right = new TreeNode<>(rightVal);
20     }
21 
22     public N getVal() {
23         return val;
24     }
25 
26     public void setVal(N val) {
27         this.val = val;
28     }
29 
30     public TreeNode<N> getLeft() {
31         return left;
32     }
33 
34     public void setLeft(N left) {
35         this.left = new TreeNode<>(left);
36     }
37 
38     public TreeNode<N> getRight() {
39         return right;
40     }
41 
42     public void setRight(N right) {
43         this.right = new TreeNode<>(right);
44     }
45 }
46 
47 
48 public class treeTest {
49 
50     public static void main(String[] args) {
51         Queue<TreeNode<Integer>> queue = new LinkedList<>();
52         TreeNode<Integer> root = new TreeNode<>(0);
53         root.setLeft(1);
54         root.setRight(2);
55         root.getLeft().setLeft(3);
56         root.getLeft().setRight(4);
57         root.getRight().setLeft(5);
58         root.getRight().setRight(6);
59         System.out.println("   " + root.getVal());
60         System.out.println("  /  \\");
61         System.out.println(" " + root.getLeft().getVal() + "    " + root.getRight().getVal());
62         System.out.println("/ \\  / \\");
63         System.out.println(root.getLeft().getLeft().getVal() + " " +  root.getLeft().getRight().getVal() + "  "
64                 + root.getRight().getLeft().getVal() + "  " + root.getRight().getRight().getVal());
65 
66         List<Integer> houXu = hou(root);
67         System.out.println(houXu);
68     }
69 
70     private static List<Integer> hou(TreeNode<Integer> root) {
71         List<Integer> resut = new ArrayList<>();
72 
73         if(null == root) return resut;
74 
75         resut.addAll(hou(root.getLeft()));
76         resut.addAll(hou(root.getRight()));
77         resut.add(root.getVal());
78 
79         return resut;
80     }
81 }
后序遍历

 输出结果:

热门相关:我有一座恐怖屋   熟女的诱惑2   拒嫁豪门,前妻太抢手   异世修真邪君   我成了暴戾帝君的小娇包