二叉树是一种树形存储结构,每个节点最多有两个子节点,通常叫做左子树和右子树。
更多二叉树的介绍可查看维基百科
注释最顶部的节点称为根节点
,在节点下方与该节点直接相连的节点叫做子节点
,反过来称为父节点
,没有子节点的称为叶子节点
,从根节点到最底下的叶子节点经过的节点数就是树的高度,也就是树的最大层数。在上面的二叉树中,1是根节点,2和3是1的子节点,1是2的父节点,4,5,6,7是叶子节点,树的高度是3。
上面这个二叉树也称为满二叉树,因为它满足除最后一层以外,其它层的节点都有两个子节点,除了满二叉树,还有一种常提到的是完全二叉树,它的特点是除最后一层以外,其它层都是满的,最后一层要么是满的,要么就是右边缺若干个节点,下面这个就是完全二叉树。
还有一些经常能听到或者用到的二叉树,比如
还有一种树,虽然不是二叉树,但是也经常用到,那就是Trie树,又叫前缀树和字典树,可以用来高效的查找字符串。
关于二叉树,最基础的就是二叉树的遍历,二叉树常见的遍历有以下几种:
上面这棵树的几种遍历结果。
前序遍历:[1,2,4,5,3,6,7]
中序遍历:[4,2,5,1,6,3,7]
后序遍历:[4,5,2,6,7,3,1]
层次遍历:[1,2,3,4,5,6,7]
下面是二叉树几种遍历方式的Java代码实现,除了层次遍历外,都有递归和迭代的实现。
1import java.util.ArrayDeque;
2import java.util.ArrayList;
3import java.util.Collections;
4import java.util.List;
5
6class TreeNode {
7 int val;
8 TreeNode left;
9 TreeNode right;
10
11 TreeNode(int x) {
12 val = x;
13 }
14}
15
16public class Main {
17
18 public static void main(String[] args) {
19 TreeNode root = buildTree("1,2,4,-,-,5,-,-,3,6,-,-,7,-,-");
20 System.out.println("层序遍历");
21 System.out.println(iterationLevel(root));
22 System.out.println("先序遍历");
23 System.out.println(recursionPreorder(root));
24 System.out.println(iterationPreorder(root));
25 System.out.println("中序遍历");
26 System.out.println(recursionInOrder(root));
27 System.out.println(iterationInOrder(root));
28 System.out.println("后序遍历");
29 System.out.println(recursionPostOrder(root));
30 System.out.println(iterationPostOrder(root));
31 }
32
33 /**
34 * 层次遍历,迭代的方式
35 */
36 public static List<Integer> iterationLevel(TreeNode root) {
37 List<Integer> res = new ArrayList<>();
38 if (root == null) {
39 return res;
40 }
41 ArrayDeque<TreeNode> queue = new ArrayDeque<>();
42 queue.offer(root);
43 while (!queue.isEmpty()) {
44 TreeNode node = queue.poll();
45 res.add(node.val);
46 if (node.left != null) {
47 queue.offer(node.left);
48 }
49 if (node.right != null) {
50 queue.offer(node.right);
51 }
52 }
53 return res;
54 }
55
56
57 /**
58 * 先序遍历,迭代的方式
59 */
60 public static List<Integer> iterationPreorder(TreeNode root) {
61 List<Integer> res = new ArrayList<>();
62 if (root == null) {
63 return res;
64 }
65 ArrayDeque<TreeNode> stack = new ArrayDeque<>();
66 while (!stack.isEmpty() || root != null) {
67 while (root != null) {
68 res.add(root.val);
69 stack.push(root);
70 root = root.left;
71 }
72 root = stack.pop();
73 root = root.right;
74 }
75 return res;
76 }
77
78 /**
79 * 先序遍历,递归的形式
80 */
81 public static List<Integer> recursionPreorder(TreeNode root) {
82 List<Integer> result = new ArrayList<>();
83 recursionPreorder(root, result);
84 return result;
85 }
86
87 public static void recursionPreorder(TreeNode root, List<Integer> result) {
88 if (root == null) {
89 return;
90 }
91 result.add(root.val);
92 recursionPreorder(root.left, result);
93 recursionPreorder(root.right, result);
94 }
95
96 /**
97 * 中序遍历,迭代的方式
98 */
99 public static List<Integer> iterationInOrder(TreeNode root) {
100 List<Integer> res = new ArrayList<>();
101 if (root == null) {
102 return res;
103 }
104 ArrayDeque<TreeNode> stack = new ArrayDeque<>();
105 while (!stack.isEmpty() || root != null) {
106 while (root != null) {
107 stack.push(root);
108 root = root.left;
109 }
110 root = stack.pop();
111 res.add(root.val);
112 root = root.right;
113 }
114 return res;
115 }
116
117 /**
118 * 中序遍历,递归的形式
119 */
120 public static List<Integer> recursionInOrder(TreeNode root) {
121 List<Integer> result = new ArrayList<>();
122 recursionInOrder(root, result);
123 return result;
124 }
125
126 public static void recursionInOrder(TreeNode root, List<Integer> result) {
127 if (root == null) {
128 return;
129 }
130 recursionInOrder(root.left, result);
131 result.add(root.val);
132 recursionInOrder(root.right, result);
133 }
134
135 /**
136 * 后序遍历,迭代的方式
137 */
138 public static List<Integer> iterationPostOrder(TreeNode root) {
139 List<Integer> res = new ArrayList<>();
140 if (root == null) {
141 return res;
142 }
143 ArrayDeque<TreeNode> stack = new ArrayDeque<>();
144 while (!stack.isEmpty() || root != null) {
145 while (root != null) {
146 stack.push(root);
147 res.add(root.val);
148 root = root.right;
149 }
150 root = stack.pop();
151 root = root.left;
152 }
153 Collections.reverse(res);
154 return res;
155 }
156
157 /**
158 * 后序遍历,递归的形式
159 */
160 public static List<Integer> recursionPostOrder(TreeNode root) {
161 List<Integer> result = new ArrayList<>();
162 recursionPostOrder(root, result);
163 return result;
164 }
165
166 public static void recursionPostOrder(TreeNode root, List<Integer> result) {
167 if (root == null) {
168 return;
169 }
170 recursionPostOrder(root.left, result);
171 recursionPostOrder(root.right, result);
172 result.add(root.val);
173 }
174
175 /**
176 * 构建二叉树
177 */
178 public static TreeNode buildTree(String data) {
179 String[] arr = data.split(",");
180 ArrayDeque<String> queue = new ArrayDeque<>();
181 for (String s : arr) {
182 queue.offer(s);
183 }
184 return deserialize(queue);
185 }
186
187 public static TreeNode deserialize(ArrayDeque<String> queue) {
188 if (queue.isEmpty()) {
189 return null;
190 }
191 String s = queue.poll();
192 if ("-".equals(s)) {
193 return null;
194 }
195 TreeNode node = new TreeNode(Integer.parseInt(s));
196 node.left = deserialize(queue);
197 node.right = deserialize(queue);
198 return node;
199 }
200}