二叉树的学习:
树
树(Tree)是n(n$\geq$0)个节点的有限集,当n=0时称为空树。在任意以可非空树中:
有且只有一个特定的根(Root)节点;
当n$\geq$0的时候,其余节点分为m(m>0)个互不相交的有限集$T_{1}$,$T_{2}$……$T_{m}$,其中每一台集合本身优势一棵树,被称为根的子树。
“树”这种数据结构很像我们生活中的“树”,这里面每个元素我们叫作“节 点”;用来连线相邻节点之间的关系,我们叫作“父子关系”
A 节点就是 B 节点的父节点,B 节点是 A 节点的子节点。B、C、D 这三个节点 的父节点是同一个节点,所以它们之间互称为兄弟节点。我们把没有父节点的节点叫作根节点,也就是图中的节点 E。我们把没有子节点的节点叫作叶子节点或者叶节点,比如图中的 G、H、I、 J、K、L 都是叶子节点。
关于“树”,还有三个比较相似的概念:高度(Height)、深 度(Depth)、层(Level)。
节点的高度=节点到叶子节点的最长路径
(边数)
节点的深度=根节点到这个节点所经历的边的个数
节点的层数=节点的深度+1
树的高度=根节点的高度
高度计数起点为0,从最底层开始计数。
深度从根开始计算向下计数。
层数计数起点为1,根节点位于第一层。
二叉树
二叉树:每个节点最多有两个“叉”,也就是两个子节点,分别是左子节点和右子节点。二叉树并不要求每个节点都有两个子节点,有的节点只有左子节点,有的节点只有右子节点。当然可以由四叉树,八叉树。
编号 2 的二叉树中,叶子节点全都在最底层,除了叶子节点之外,每个节点都有左右两个子节点,这种二叉树就叫作满二叉树。 编号 3 的二叉树中,叶子节点都在最底下两层,最后一层的叶子节点都靠左排列,并且除了最后一 层,其他层的节点个数都要达到最大,这种二叉树叫作完全二叉树。
在满足满二叉树的性质后,最后一层的叶子节点均需在最左边。
实现
想要存储一棵二叉树,我们有两种方法,一种是基于指针或者引用的二叉链式存储法,一种是基于数组的顺序存储法。 每个节点有三个字段,其中一个存储数据,另外两个是指向左右子节点的指针。我们只要拎住根节点,就可以通过左 右子节点的指针,把整棵树都串起来。
完全二叉树,仅仅“浪费”了一个下标为 0 的存储位置。但是如果是非完全二叉树,会浪费很多的数组存储空间。
遍历
前序遍历:对于树中的任意节点来说,先打印这个节点,然后再打印它的左子树,最后打印 它的右子树。 中序遍历:对于树中的任意节点来说,先打印它的左子树,然后再打印它本身,最后打印它 的右子树。 后序遍历:对于树中的任意节点来说,先打印它的左子树,然后再打印它的右子树,最后打 印这个节点本身
二叉树的遍历是一个递归的过程。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 import java.util.LinkedList;import java.util.Queue;import java.util.Stack;public class BST <E extends Comparable <E >> { private class Node { public E e; public Node left, right; public Node (E e) { this .e = e; left = null ; right = null ; } } private Node root; private int size; public BST () { root = null ; size = 0 ; } public int size () { return size; } public boolean isEmpty () { return size == 0 ; } public void add (E e) { root = add(root, e); } private Node add (Node node, E e) { if (node == null ){ size ++; return new Node(e); } if (e.compareTo(node.e) < 0 ) node.left = add(node.left, e); else if (e.compareTo(node.e) > 0 ) node.right = add(node.right, e); return node; } public boolean contains (E e) { return contains(root, e); } private boolean contains (Node node, E e) { if (node == null ) return false ; if (e.compareTo(node.e) == 0 ) return true ; else if (e.compareTo(node.e) < 0 ) return contains(node.left, e); else return contains(node.right, e); } public void preOrder () { preOrder(root); } private void preOrder (Node node) { if (node == null ) return ; System.out.println(node.e); preOrder(node.left); preOrder(node.right); } public void preOrderNR () { Stack<Node> stack = new Stack<>(); stack.push(root); while (!stack.isEmpty()){ Node cur = stack.pop(); System.out.println(cur.e); if (cur.right != null ) stack.push(cur.right); if (cur.left != null ) stack.push(cur.left); } } public void inOrder () { inOrder(root); } private void inOrder (Node node) { if (node == null ) return ; inOrder(node.left); System.out.println(node.e); inOrder(node.right); } public void postOrder () { postOrder(root); } private void postOrder (Node node) { if (node == null ) return ; postOrder(node.left); postOrder(node.right); System.out.println(node.e); } public void levelOrder () { Queue<Node> q = new LinkedList<>(); q.add(root); while (!q.isEmpty()){ Node cur = q.remove(); System.out.println(cur.e); if (cur.left != null ) q.add(cur.left); if (cur.right != null ) q.add(cur.right); } } public E minimum () { if (size == 0 ) throw new IllegalArgumentException("BST is empty!" ); return minimum(root).e; } private Node minimum (Node node) { if (node.left == null ) return node; return minimum(node.left); } public E maximum () { if (size == 0 ) throw new IllegalArgumentException("BST is empty" ); return maximum(root).e; } private Node maximum (Node node) { if (node.right == null ) return node; return maximum(node.right); } public E removeMin () { E ret = minimum(); root = removeMin(root); return ret; } private Node removeMin (Node node) { if (node.left == null ){ Node rightNode = node.right; node.right = null ; size --; return rightNode; } node.left = removeMin(node.left); return node; } public E removeMax () { E ret = maximum(); root = removeMax(root); return ret; } private Node removeMax (Node node) { if (node.right == null ){ Node leftNode = node.left; node.left = null ; size --; return leftNode; } node.right = removeMax(node.right); return node; } public void remove (E e) { root = remove(root, e); } private Node remove (Node node, E e) { if ( node == null ) return null ; if ( e.compareTo(node.e) < 0 ){ node.left = remove(node.left , e); return node; } else if (e.compareTo(node.e) > 0 ){ node.right = remove(node.right, e); return node; } else { if (node.left == null ){ Node rightNode = node.right; node.right = null ; size --; return rightNode; } if (node.right == null ){ Node leftNode = node.left; node.left = null ; size --; return leftNode; } Node successor = minimum(node.right); successor.right = removeMin(node.right); successor.left = node.left; node.left = node.right = null ; return successor; } } @Override public String toString () { StringBuilder res = new StringBuilder(); generateBSTString(root, 0 , res); return res.toString(); } private void generateBSTString (Node node, int depth, StringBuilder res) { if (node == null ){ res.append(generateDepthString(depth) + "null\n" ); return ; } res.append(generateDepthString(depth) + node.e +"\n" ); generateBSTString(node.left, depth + 1 , res); generateBSTString(node.right, depth + 1 , res); } private String generateDepthString (int depth) { StringBuilder res = new StringBuilder(); for (int i = 0 ; i < depth ; i ++) res.append("-- " ); return res.toString(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class Order { public static void main (String[] args) { BST<Integer> bst = new BST<>(); int [] nums = {5 , 3 , 6 , 8 , 4 , 2 }; for (int num: nums) bst.add(num); System.out.println(bst); bst.preOrder(); System.out.println(); bst.inOrder(); System.out.println(); bst.postOrder(); System.out.println(); bst.levelOrder(); System.out.println(); } }
遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 5 --3 ----2 ------null ------null ----4 ------null ------null --6 ----null ----8 ------null ------null 5 3 2 4 6 8 2 3 4 5 6 8 2 4 3 8 6 5 5 3 6 2 4 8
删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import java.util.ArrayList;import java.util.Random;public class Remove { public static void main (String[] args) { BST<Integer> bst = new BST<>(); Random random = new Random(); int n = 10 ; for (int i = 0 ; i < n ; i ++) bst.add(random.nextInt(10000 )); System.out.println(bst); ArrayList<Integer> nums = new ArrayList<>(); while (!bst.isEmpty()) nums.add(bst.removeMin()); System.out.println(nums); for (int i = 1 ; i < nums.size() ; i ++) if (nums.get(i - 1 ) > nums.get(i)) throw new IllegalArgumentException("Error!" ); System.out.println("removeMin test completed." ); for (int i = 0 ; i < n ; i ++) bst.add(random.nextInt(10000 )); nums = new ArrayList<>(); while (!bst.isEmpty()) nums.add(bst.removeMax()); System.out.println(nums); for (int i = 1 ; i < nums.size() ; i ++) if (nums.get(i - 1 ) < nums.get(i)) throw new IllegalArgumentException("Error!" ); System.out.println("removeMax test completed." ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 5022 --1869 ----617 ------null ------1370 --------null --------null ----3497 ------null ------null --5729 ----null ----9598 ------8387 --------6796 ----------null ----------8167 ------------null ------------null --------null ------null [617 , 1370 , 1869 , 3497 , 5022 , 5729 , 6796 , 8167 , 8387 , 9598 ] removeMin test completed. 7926 --5532 ----309 ------null ------2171 --------null --------4294 ----------null ----------null ----7031 ------6053 --------null --------6737 ----------null ----------null ------null --8619 ----null ----8677 ------null ------null [8677 , 8619 , 7926 , 7031 , 6737 , 6053 , 5532 , 4294 , 2171 , 309 ] removeMax test completed.