1 function TreeNode(val) { // 树节点构造方式
2 this.val = val;
3 this.left = null;
4 this.right = null;
5 }
6
7 function generateTree() {
8 let root = new TreeNode(10);
9 let left1 = new TreeNode(5);
10 let left2 = new TreeNode(4);
11 let left3 = new TreeNode(7);
12 let right1 = new TreeNode(12);
13 let right2 = new TreeNode(11);
14 let right3 = new TreeNode(15);
15 let right4 = new TreeNode(13);
16 root.left = left1;
17 left1.left = left2;
18 left1.right = left3;
19 root.right = right1;
20 right1.left = right2;
21 right1.right = right3;
22 right3.left = right4;
23 return root;
24 }
25
26 function visit(node) { // 遍历方式-打印出来
27 console.log(node.val);
28 }
29
30 // 递归方式
31 // 前(先)序遍历递归方式
32 function DLR_recursion(root) {
33 root && visit(root);
34 root.left && DLR_recursion(root.left);
35 root.right && DLR_recursion(root.right);
36 }
37
38 // 中序遍历递归方式
39 function LDR_recursion(root) {
40 root.left && LDR_recursion(root.left);
41 root && visit(root);
42 root.right && LDR_recursion(root.right);
43 }
44
45 // 后序遍历递归方式
46 function RDL_recursion(root) {
47 root.left && RDL_recursion(root.left);
48 root.right && RDL_recursion(root.right);
49 root && visit(root);
50 }
51
52 // 非递归方式
53 // 前(先)序遍历非递归方式
54 function DLR(root) {
55 let arr = []; // 维护一个栈
56 root && arr.push(root);
57 while (arr.length !== 0) {
58 let temp = arr.pop();
59 visit(temp);
60 if (temp.right !== null) { // 这里入栈顺序是先右后左,这样由于先进后出,所以符合右子树后出,为先序遍历
61 arr.push(temp.right);
62 }
63 if (temp.left !== null) {
64 arr.push(temp.left);
65 }
66 }
67 }
68
69 // 中序非递归遍历
70 function LDR(root) {
71 let arr = [];
72 while (true) {
73 while (root !== null) {
74 arr.push(root);
75 root = root.left;
76 }
77 // 循环的结束条件是数组长度为0,遍历完成
78 if (arr.length === 0) {
79 break;
80 }
81 let temp = arr.pop();
82 visit(temp); // 访问左子树的根节点
83 root = temp.right; // 左子树的右子节点
84 }
85 }
86
87 // 后序非递归遍历(与前序遍历相反)
88 function RDL(root) {
89 let arr = [], res = [];
90 root && arr.push(root);
91 while (arr.length !== 0) {
92 let temp = arr.pop();
93 res.push(temp);
94 if (temp.left !== null) {
95 arr.push(temp.left);
96 }
97 if (temp.right !== null) {
98 arr.push(temp.right);
99 }
100 }
101 res.reverse();
102 res.forEach(item => visit(item));
103 }
104
105
106 function run() {
107 let tree = generateTree();
108 console.log("前(先)序递归遍历", DLR_recursion(tree));
109 console.log("前(先)序递归遍历", DLR(tree));
110
111 console.log("中序递归遍历", LDR_recursion(tree));
112 console.log("中序非递归遍历", LDR(tree));
113
114 console.log("后序递归遍历", RDL_recursion(tree));
115 console.log("后序非递归遍历", RDL(tree));
116
117 }
118
119 run();
结果输出:
前(先)序递归遍历:10,5,4,7,12,11,15,13
前(先)序非递归遍历:10,5,4,7,12,11,15,13
中序递归遍历:4,5,7,10,11,12,13,15
中序非递归遍历:4,5,7,10,11,12,13,15
后序递归遍历:4,7,5,11,13,15,12,10
后序非递归遍历:4,7,5,11,13,15,12,10