数据结构之树结构
树结构:一种描述非线性层次关系的数据结构 ,其中重要的是树的概念。
树:n个数据结点的集合,在该集合中包含一个根结点。根结点之下分布着一些互不交叉的子集合,
这些子集合也就是根结点的子树。
树结构的基本特征:
在一个树结构中,有且仅有一个结点没有直接前驱,这个结点就是树的根结点;
除根结点外,其余每个结点有且仅有一个直接前驱;
每个结点可以有任意多个直接后继。
1 Java代码实现: 2 3 4 5 /** 6 * 非线性存储结构 -> 链表实现的二叉查找树 7 * 8 * 初始化 计算表长 获取结点 查找结点 插入结点 删除结点 9 * 10 * @see java.util.TreeMap 11 * 12 */ 13 public class Tree<T> { 14 15 /** 根结点 */ 16 private Node<T> root; 17 18 /** 比较器 */ 19 private final Comparator<T> comparator; 20 21 /** 树的容量 */ 22 private int size = 0; 23 24 /** 初始化 */ 25 public Tree() { 26 comparator = null; 27 } 28 29 /** 初始化 */ 30 public Tree(Comparator<T> comparator) { 31 this.comparator = comparator; 32 } 33 34 /** 初始化 */ 35 public Tree(Comparator<T> comparator, Collection<T> c) { 36 this.comparator = comparator; 37 addAll(c); 38 } 39 40 /* 添加集合中所有元素到树 */ 41 private boolean addAll(Collection<T> c) { 42 boolean modified = false; 43 for (T t : c) 44 if (add(t)) 45 modified = true; 46 return modified; 47 } 48 49 /** 添加结点 */ 50 public boolean add(T t) { 51 Node<T> n = root; 52 if (n == null) { 53 root = new Node<>(t, null); 54 size++; 55 return true; 56 } 57 Node<T> parent = null; 58 int m = 0; 59 Comparator<? super T> c = comparator; 60 if (c != null) { 61 do { 62 parent = n; 63 m = c.compare(n.data, t); 64 if (m < 0) { 65 n = n.left; 66 } else if (m > 0) { 67 n = n.right; 68 } else { 69 // 相同类型元素的处理: 不能存储两个相同的数据. 70 } 71 } while (n != null); 72 } else { 73 @SuppressWarnings("unchecked") 74 Comparable<? super T> cc = (Comparable<? super T>) t; 75 do { 76 parent = n; 77 m = cc.compareTo(n.data); 78 if (m < 0) { 79 n = n.left; 80 } else if (m > 0) { 81 n = n.right; 82 } else { 83 // 相同类型元素的处理: 不能存储两个相同的数据. 84 } 85 } while (n != null); 86 } 87 Node<T> e = new Node<>(t, parent); 88 if (m < 0) 89 parent.left = e; 90 else 91 parent.right = e; 92 93 size++; 94 return true; 95 } 96 97 /** 删除结点 */ 98 public boolean remove(T t) { 99 Node<T> n = getNode(t); 100 if (n == null) 101 return false; 102 deleteNode(n); 103 return true; 104 } 105 106 /** 树中是否存在某个对象 */ 107 public boolean contains(T o) { 108 return getNode(o) == null ? false : true; 109 } 110 111 /* 获得树结点 */ 112 private final Node<T> getNode(T t) { 113 @SuppressWarnings("unchecked") 114 Comparable<? super T> c = (Comparable<? super T>) t; 115 Node<T> n = root; 116 while (n != null) { // 树的遍历 117 int m = c.compareTo(n.data); 118 if (m < 0) 119 n = n.left; 120 else if (m > 0) 121 n = n.right; 122 else 123 return n; // 找到存储数据的节点 124 } 125 return null; 126 } 127 128 /* 删除树结点 */ 129 private final void deleteNode(Node<T> node) { 130 size--; 131 if (node.left != null && node.right != null) { 132 Node<T> n = successor(node); // 返回后继结点 133 node.data = n.data; 134 node = n; 135 } 136 137 Node<T> r = (node.left != null ? node.left : node.right); 138 if (r != null) { // node.left != null 139 r.parent = node.parent; // 连接节点replacement到node的parent 140 if (node.parent == null) // node就是root 141 root = r; // 删除node,replacement变为root 142 else if (node == node.parent.left) 143 node.parent.left = r; 144 else 145 node.parent.right = r; 146 147 node.left = node.right = node.parent = null; // 删除 148 } else if (node.parent == null) { // 149 root = null; 150 } else { // 151 if (node.parent != null) { 152 if (node == node.parent.left) 153 node.parent.left = null; 154 else if (node == node.parent.right) 155 node.parent.right = null; 156 node.parent = null; 157 } 158 } 159 } 160 161 /* 查找后继结点 */ 162 private static final <T> Node<T> successor(Node<T> node) { 163 if (node == null) { 164 return null; 165 } else if (node.right != null) { 166 Node<T> p = node.right; 167 while (p.left != null) 168 p = p.left; 169 return p; 170 } else { 171 Node<T> p = node.parent; 172 Node<T> c = node; 173 while (p != null && c == p.right) { 174 c = p; 175 p = p.parent; 176 } 177 return p; 178 } 179 } 180 181 /* 查找前任结点 */ 182 private static final <T> Node<T> predecessor(Node<T> node) { 183 if (node == null) { 184 return null; 185 } else if (node.left != null) { 186 Node<T> n = node.left; 187 while (n.right != null) 188 n = n.right; 189 return n; 190 } else { 191 Node<T> n = node.parent; 192 Node<T> c = node; 193 while (n != null && c == n.left) { 194 c = n; 195 n = n.parent; 196 } 197 return n; 198 } 199 } 200 201 /* 遍历子树 */ 202 String orderTree(Node<T> node) { // 使用递归,中序遍历子树. 203 if (node != null) { 204 orderTree(node.left); 205 System.out.print(node.data + ", "); 206 orderTree(node.right); 207 } 208 return null; 209 } 210 211 /** 二叉树的结点 */ 212 private static final class Node<T> { 213 214 T data; // 数据 215 Node<T> parent; // 父亲结点 216 Node<T> left; // 左子树(小) 217 Node<T> right; // 右子树(大) 218 219 Node(T data,Node<T> parent) { 220 this.data = data; 221 this.parent = parent; 222 } 223 224 @Override 225 public int hashCode() { 226 return data.hashCode(); 227 } 228 229 @Override 230 public boolean equals(Object obj) { 231 return data.equals(obj); 232 } 233 234 public String toString() { 235 return data.toString(); 236 } 237 238 } 239 240 /** 树迭代器 */ 241 final class TreeIterator implements Iterator<Node<T>> { 242 243 Node<T> next; // 下一个 244 Node<T> prev; // 上一个 245 246 TreeIterator(Node<T> first) { 247 next = first; 248 prev = null; 249 } 250 251 @Override 252 public boolean hasNext() { 253 return next != null; 254 } 255 256 @Override 257 public Node<T> next() { 258 Node<T> e = next; 259 if (e == null) 260 throw new NoSuchElementException(); 261 next = successor(e); 262 prev = e; 263 return e; 264 } 265 266 public Node<T> prev() { 267 Node<T> e = next; 268 if (e == null) 269 throw new NoSuchElementException(); 270 next = predecessor(e); 271 prev = e; 272 return e; 273 } 274 275 } 276 277 /** 获得迭代器 */ 278 public Iterator<Node<T>> iterator() { 279 Node<T> first = root; 280 while (first.left != null) //找到第一个节点,即最小值节点. 281 first = first.left; 282 return new TreeIterator(first); 283 } 284 285 /** 计算容量 */ 286 public int size() { 287 return size; 288 } 289 290 /** 字符串输出 */ 291 public String toString() { 292 Iterator<Node<T>> i = iterator(); 293 if (!i.hasNext()) 294 return "{}"; 295 StringBuilder builder = new StringBuilder(); 296 builder.append('{'); 297 for (;;) { 298 Node<T> e = i.next(); 299 builder.append(e.data); 300 if (!i.hasNext()) 301 return builder.append('}').toString(); 302 builder.append(',').append(' '); 303 } 304 } 305 306 }