├── Graph └── Graph.java ├── Hash └── HashSet.java ├── List ├── ArrayList.java ├── LinkedList │ ├── DList.java │ ├── DListDriver.java │ └── DListNode.java └── Stack.java ├── README.md └── Tree ├── BST.java ├── RedBlackTree.java └── Trie.java /Graph/Graph.java: -------------------------------------------------------------------------------- 1 | package graph; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.Iterator; 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.NoSuchElementException; 11 | import java.util.PriorityQueue; 12 | import java.util.Queue; 13 | import java.util.Set; 14 | 15 | public class Graph { 16 | private HashSet vertex; 17 | private HashMap>> adj; 18 | 19 | private int V; 20 | private int E; 21 | 22 | public Graph() { 23 | V = E = 0; 24 | vertex = new HashSet<>(); 25 | adj = new HashMap<>(); 26 | } 27 | 28 | private static class Edge { 29 | private final Type2 V1, V2; 30 | private final int WEIGHT; 31 | 32 | public Edge(Type2 item1, Type2 item2, int weight) { 33 | V1 = item1; 34 | V2 = item2; 35 | WEIGHT = weight; 36 | } 37 | } 38 | 39 | private class Vertex implements Comparable> { 40 | private Type3 v; 41 | private int WEIGHT; 42 | 43 | public Vertex(Type3 v, int weight) { 44 | this.v = v; 45 | this.WEIGHT = weight; 46 | } 47 | 48 | @Override 49 | public int compareTo(Vertex o) { 50 | // TODO Auto-generated method stub 51 | return this.WEIGHT - o.WEIGHT; 52 | } 53 | } 54 | 55 | public int E() { 56 | return E; 57 | } 58 | public int V() { 59 | return V; 60 | } 61 | 62 | public void addVertex(Type item) { 63 | vertex.add(item); 64 | adj.put(item, new LinkedList<>()); 65 | ++V; 66 | } 67 | 68 | public void addEdge(Edge edge) { 69 | validVertex(edge.V1); 70 | validVertex(edge.V2); 71 | adj.get(edge.V1).add(edge); 72 | adj.get(edge.V2).add(edge); 73 | ++E; 74 | } 75 | 76 | private void validVertex(Type vertex) { 77 | if(!adj.containsKey(vertex)) throw new NoSuchElementException("invalid vertex"); 78 | } 79 | 80 | 81 | public Map shortesDijkstra(Type v) { 82 | Map map = new HashMap<>(); 83 | PriorityQueue> pq = new PriorityQueue<>(); 84 | Set set = new HashSet<>(); 85 | for(Type vv : vertex) { 86 | set.add(vv); 87 | } 88 | map.put(v, 0); 89 | set.remove(v); 90 | while(!set.isEmpty()) { 91 | for(Edge edge : adj.get(v)) { 92 | Type v2 = edge.V1==v ? edge.V2 : edge.V1; 93 | if(set.contains(v2)) pq.add(new Vertex(v2, edge.WEIGHT+map.get(v))); 94 | } 95 | Vertex nextVertex = pq.poll(); 96 | v = nextVertex.v; 97 | map.put(nextVertex.v, nextVertex.WEIGHT); 98 | set.remove(v); 99 | } 100 | return map; 101 | } 102 | 103 | 104 | public List bfs() { 105 | List list = new ArrayList<>(); 106 | Map visited = new HashMap<>(); 107 | for(Type v : vertex) { 108 | visited.put(v, false); // initialize visited map 109 | } 110 | Map parent = new HashMap<>(); 111 | Iterator it = vertex.iterator(); 112 | while(it.hasNext()) { 113 | bfs(it.next(), visited, parent, list); // run bfs on every node 114 | } 115 | // System.out.println(parent); 116 | return list; 117 | } 118 | private void bfs(Type v, Map visited, Map parent, List list) { 119 | if(!visited.get(v)) { 120 | list.add(v); 121 | visited.put(v, true); 122 | Queue q = new LinkedList<>(); 123 | q.offer(v); 124 | while(!q.isEmpty()) { 125 | LinkedList> a = adj.get(q.poll()); 126 | for(Edge edge : a) { 127 | Type next = edge.V1 == v ? edge.V2 : edge.V1; 128 | if(visited.get(next)) continue; 129 | else { 130 | visited.put(next, true); 131 | list.add(next); 132 | parent.put(next, v); // add parent pointer 133 | q.offer(next); // enqueue 134 | } 135 | } 136 | } 137 | } 138 | } 139 | 140 | 141 | public List dfs() { 142 | List list = new ArrayList<>(); 143 | Map visited = new HashMap<>(); 144 | for(Type v : vertex) { 145 | visited.put(v, false); 146 | } 147 | Iterator it = vertex.iterator(); 148 | while(it.hasNext()) { 149 | dfs(it.next(), visited, list); 150 | } 151 | return list; 152 | } 153 | private void dfs(Type v, Map visited, List list) { 154 | if(!visited.get(v)) { 155 | //System.out.println(v); 156 | list.add(v); 157 | visited.put(v, true); 158 | LinkedList> a = adj.get(v); 159 | for(Edge edge : a) { 160 | Type next = edge.V1 == v ? edge.V2 : edge.V1; 161 | if(visited.get(next)) continue; 162 | else dfs(next, visited, list); 163 | } 164 | } 165 | } 166 | 167 | public static void main(String[] args) { 168 | Graph g = new Graph<>(); 169 | g.addVertex('A'); 170 | g.addVertex('B'); 171 | g.addVertex('C'); 172 | g.addVertex('D'); 173 | g.addVertex('E'); 174 | 175 | g.addEdge(new Edge<>('A', 'B', 10)); 176 | g.addEdge(new Edge<>('A', 'C', 3)); 177 | g.addEdge(new Edge<>('A', 'E', 1)); 178 | g.addEdge(new Edge<>('B', 'C', 2)); 179 | g.addEdge(new Edge<>('C', 'D', 5)); 180 | g.addEdge(new Edge<>('D', 'E', -2)); 181 | g.addEdge(new Edge<>('C', 'E', 8)); 182 | 183 | System.out.println("vertex count: " + g.V()); 184 | System.out.println("edge count: " + g.E()); 185 | 186 | 187 | //System.out.println(g.bfs()); 188 | //System.out.println(g.dfs()); 189 | 190 | //System.out.println(g.adj); 191 | 192 | System.out.println(g.shortesDijkstra('A')); 193 | //System.out.println(g.dfs()); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /Hash/HashSet.java: -------------------------------------------------------------------------------- 1 | package hash; 2 | 3 | import java.util.NoSuchElementException; 4 | import java.util.Iterator; 5 | 6 | public class HashSet { 7 | 8 | private int CAPACITY; 9 | private float LF; 10 | private int MAX_SIZE; 11 | private List[] arr; 12 | private int size = 0; 13 | 14 | @SuppressWarnings("unchecked") 15 | public HashSet() { 16 | CAPACITY = 16; 17 | LF = 0.75f; 18 | MAX_SIZE = (int)(LF*CAPACITY); 19 | arr = new List[CAPACITY]; 20 | for(int i=0; i(); 22 | } 23 | } 24 | 25 | @SuppressWarnings("unchecked") 26 | public HashSet(int initialCapacity) { 27 | assert(initialCapacity > 0); 28 | 29 | CAPACITY = getNearestPowerTwo(initialCapacity); 30 | MAX_SIZE = (int)(LF*CAPACITY); 31 | 32 | arr = new List[CAPACITY]; 33 | for(int i=0; i(); 35 | } 36 | } 37 | 38 | @SuppressWarnings("unchecked") 39 | public HashSet(int initialCapacity, int loadFactor) { 40 | assert(initialCapacity > 0); 41 | assert(loadFactor > 0 && loadFactor <= 1); 42 | 43 | CAPACITY = getNearestPowerTwo(initialCapacity); 44 | LF = loadFactor; 45 | MAX_SIZE = (int)(LF*CAPACITY); 46 | 47 | arr = new List[CAPACITY]; 48 | for(int i=0; i(); 50 | } 51 | } 52 | 53 | public int size() { 54 | return size; 55 | } 56 | 57 | public boolean isEmpty() { 58 | return size==0; 59 | } 60 | 61 | public boolean add(T item) { 62 | if(contains(item)) return false; // already existed 63 | if(size==MAX_SIZE) resize(); // resize 64 | addItem(item); // add item into array 65 | ++size; // increase size 66 | return true; 67 | } 68 | private void addItem(T item) { 69 | int index = hashing(item); // rehash 70 | arr[index].add(item); 71 | } 72 | 73 | public boolean contains(T item) { 74 | int index = hashing(item); 75 | List list = arr[index]; 76 | Iterator it = list.iterator(); 77 | while(it.hasNext()) { 78 | if(it.next().equals(item)) return true; 79 | } 80 | return false; 81 | } 82 | 83 | public boolean remove(T item) { 84 | int index = hashing(item); 85 | List list = arr[index]; 86 | Iterator it = list.iterator(); 87 | while(it.hasNext()) { 88 | if(it.next().equals(item)) { 89 | it.remove(); 90 | --size; 91 | return true; 92 | } 93 | } 94 | return false; 95 | } 96 | 97 | /* 98 | // needs to implement the iterator method 99 | public Iterator iterator() { 100 | return new HashSetIterator(); 101 | } 102 | private class HashSetIterator implements Iterator { 103 | private List current = null, next = null; 104 | private T currentVal = null; 105 | private int currentId = 0; 106 | 107 | public HashSetIterator() { 108 | while(currentId < CAPACITY) { 109 | if(!arr[currentId].isEmpty()) { 110 | next = (List) arr[currentId]; 111 | currentVal = current; 112 | break; 113 | } 114 | ++currentId; 115 | } 116 | } 117 | 118 | public boolean hasNext() { 119 | return next != null; 120 | } 121 | 122 | public T next() { 123 | if(next==null) throw new NoSuchElementException(); 124 | 125 | T item = next.get(0); 126 | if(it.hasNext()) item = it.next(); 127 | else { 128 | while(++currentId < N) { 129 | if(!arr[currentId].isEmpty()) { 130 | current = arr[currentId]; 131 | it = arr[currentId].iterator(); 132 | } 133 | } 134 | } 135 | 136 | Iterator it = arr[currentId].iterator(); 137 | while(it.hasNext()) { 138 | current = 139 | } 140 | return item; 141 | } 142 | } 143 | */ 144 | 145 | private int getNearestPowerTwo(int capacity) { 146 | int shifts = 0; 147 | while(capacity > 0) { 148 | capacity = capacity >> 1; 149 | ++shifts; 150 | } 151 | return 1 << ++shifts; 152 | } 153 | 154 | @SuppressWarnings("unchecked") 155 | private boolean resize() { 156 | int temp = CAPACITY; 157 | CAPACITY = CAPACITY<<1; 158 | MAX_SIZE = (int)(LF*CAPACITY); 159 | List[] arrCopy = arr; 160 | arr = new List[CAPACITY]; 161 | for(int i=0; i(); 163 | } 164 | for(int i=0; i it = arrCopy[i].iterator(); 166 | while(it.hasNext()) { 167 | addItem(it.next()); 168 | } 169 | } 170 | return true; 171 | } 172 | 173 | // following hash() method in HashMap.class (Java JDK 1.8) 174 | public int hashing(T item) { 175 | int h; 176 | int hash = (item == null) ? 0 : (h = item.hashCode()) ^ (h >>> 16); 177 | return hash & (CAPACITY-1); 178 | } 179 | 180 | public String toString() { 181 | StringBuilder sb = new StringBuilder(""); 182 | for(int i=0; i { 191 | public Node head, tail; 192 | public int size; 193 | public List() { 194 | head = tail = null; 195 | size = 0; 196 | } 197 | 198 | public boolean isEmpty() { 199 | return size==0; 200 | } 201 | public void add(T val) { 202 | if(head==null) { 203 | head = tail = new Node<>(val); 204 | } 205 | else { 206 | tail.next = new Node<>(val); 207 | tail = tail.next; 208 | } 209 | ++size; 210 | } 211 | public void remove(T val) { 212 | Node current = head, prev = new Node<>(val); 213 | prev.next = current; 214 | while(current != null) { 215 | if(val.equals(current.val)) { 216 | prev.next = current.next; 217 | --size; 218 | return; 219 | } 220 | } 221 | throw new NoSuchElementException(); 222 | } 223 | 224 | public String toString() { 225 | Node current = head; 226 | StringBuilder sb = new StringBuilder(); 227 | sb.append("["); 228 | while(current!=null) { 229 | sb.append(current.val + ","); 230 | current = current.next; 231 | } 232 | if(sb.length()>1) sb.deleteCharAt(sb.length()-1); 233 | sb.append("]"); 234 | return sb.toString(); 235 | } 236 | 237 | public Iterator iterator() { 238 | return new ListIterator<>(); 239 | } 240 | private class ListIterator implements Iterator { 241 | Node next; 242 | public ListIterator() { 243 | next = (Node) head; 244 | } 245 | public boolean hasNext() { 246 | return next != null; 247 | } 248 | public T next() { 249 | if(next==null) throw new NoSuchElementException(); 250 | T val = next.val; 251 | next = next.next; 252 | return val; 253 | } 254 | // incorrect and needs to be corrected! 255 | public void remove() { 256 | if(next==null) throw new NoSuchElementException(); 257 | T val = next.val; 258 | next = next.next; 259 | } 260 | } 261 | 262 | private class Node { 263 | public T val; 264 | public Node next; 265 | public Node(T val) { 266 | this.val = val; 267 | this.next = null; 268 | } 269 | } 270 | } 271 | 272 | public static void main(String[] args) { 273 | 274 | HashSet list = new HashSet<>(); 275 | 276 | System.out.println("add(abc)"); 277 | list.add("abc"); 278 | System.out.println("add(def)"); 279 | list.add("def"); 280 | 281 | System.out.println("items: " + list); 282 | System.out.println("size: " + list.size()); 283 | 284 | System.out.println(); 285 | 286 | System.out.println("add(ghi)"); 287 | list.add("ghi"); 288 | 289 | System.out.println("items: " + list); 290 | System.out.println("size: " + list.size()); 291 | 292 | System.out.println(); 293 | 294 | System.out.println("add(jkl)"); 295 | list.add("jkl"); 296 | 297 | System.out.println("items: " + list); 298 | System.out.println("size: " + list.size()); 299 | 300 | System.out.println(); 301 | 302 | System.out.println("add(bcd)"); 303 | list.add("bcd"); 304 | 305 | System.out.println("items: " + list); 306 | System.out.println("size: " + list.size()); 307 | 308 | System.out.println(); 309 | System.out.println("add(abcdefg)"); 310 | list.add("abcdefg"); 311 | 312 | System.out.println("items: " + list); 313 | System.out.println("size: " + list.size()); 314 | System.out.println("contains(abcd): " + list.contains("abcd")); 315 | System.out.println("contains(a): " + list.contains("a")); 316 | System.out.println("contains(b): " + list.contains("b")); 317 | System.out.println("contains(): " + list.contains("")); 318 | 319 | 320 | System.out.println(); 321 | 322 | System.out.println("remove(bcd): "); 323 | list.remove("bcd"); 324 | System.out.println("items: " + list); 325 | System.out.println("size: " + list.size()); 326 | 327 | 328 | System.out.println(); 329 | 330 | System.out.println("remove(bcd): "); 331 | list.remove("bcd"); 332 | System.out.println("items: " + list); 333 | System.out.println("size: " + list.size()); 334 | 335 | System.out.println(); 336 | 337 | 338 | System.out.println("add(abc)"); 339 | list.add("abc"); 340 | System.out.println("add(abc)"); 341 | list.add("abc"); 342 | System.out.println("add(abc)"); 343 | list.add("abc"); 344 | System.out.println("add(b)"); 345 | list.add("b"); 346 | 347 | System.out.println("items: " + list); 348 | System.out.println("size: " + list.size()); 349 | 350 | System.out.println(); 351 | 352 | System.out.println("remove(a): "); 353 | list.remove("a"); 354 | System.out.println("remove(abcdefg): "); 355 | list.remove("abcdefg"); 356 | System.out.println("remove(def): "); 357 | list.remove("def"); 358 | System.out.println("remove(ghi): "); 359 | list.remove("ghi"); 360 | 361 | System.out.println("items: " + list); 362 | System.out.println("size: " + list.size()); 363 | System.out.println(); 364 | 365 | 366 | System.out.println("add(bbb)"); 367 | list.add("bbb"); 368 | System.out.println("add(bbbbb)"); 369 | list.add("bbbbb"); 370 | System.out.println("add(abbbc)"); 371 | list.add("abbbc"); 372 | System.out.println("add(bbbbbbb)"); 373 | list.add("bbbbbbb"); 374 | System.out.println("add(abbbbbc)"); 375 | list.add("abbbbbc"); 376 | System.out.println("add(bbbbbbbbb)"); 377 | list.add("bbbbbbbbb"); 378 | System.out.println("add(abbbbbbbc)"); 379 | list.add("abbbbbbbc"); 380 | System.out.println("add(bbbbbbbbbbb)"); 381 | list.add("bbbbbbbbbbb"); 382 | System.out.println("add(abbbbbbbbbc)"); 383 | list.add("abbbbbbbbbc"); 384 | System.out.println("add(bbbbbbbbbbbbb)"); 385 | list.add("bbbbbbbbbbbbb"); 386 | System.out.println("add(abbbbbbbbbbbc)"); 387 | list.add("abbbbbbbbbbbc"); 388 | System.out.println("add(bbbbbbbbbbbbbbb)"); 389 | list.add("bbbbbbbbbbbbbbb"); 390 | System.out.println("add(abbbbbbbbbbbbbc)"); 391 | list.add("abbbbbbbbbbbbbc"); 392 | System.out.println("add(bbbbbbbbbbbbbbbbb)"); 393 | list.add("bbbbbbbbbbbbbbbbb"); 394 | 395 | System.out.println("items: " + list); 396 | System.out.println("size: " + list.size()); 397 | 398 | 399 | 400 | 401 | 402 | /* 403 | // integer set 404 | HashSet list = new HashSet<>(); 405 | 406 | System.out.println("add(5)"); 407 | list.add(5); 408 | System.out.println("add(4)"); 409 | list.add(4); 410 | 411 | System.out.println("items: " + list); 412 | System.out.println("size: " + list.size()); 413 | 414 | System.out.println(); 415 | 416 | System.out.println("add(3)"); 417 | list.add(3); 418 | 419 | System.out.println("items: " + list); 420 | System.out.println("size: " + list.size()); 421 | 422 | System.out.println(); 423 | 424 | System.out.println("add(2)"); 425 | list.add(2); 426 | 427 | System.out.println("items: " + list); 428 | System.out.println("size: " + list.size()); 429 | 430 | System.out.println(); 431 | 432 | System.out.println("add(1)"); 433 | list.add(1); 434 | 435 | System.out.println("items: " + list); 436 | System.out.println("size: " + list.size()); 437 | 438 | System.out.println(); 439 | System.out.println("add(0)"); 440 | list.add(0); 441 | 442 | System.out.println("items: " + list); 443 | System.out.println("size: " + list.size()); 444 | System.out.println("contains(0): " + list.contains(0)); 445 | System.out.println("contains(1): " + list.contains(1)); 446 | System.out.println("contains(2): " + list.contains(2)); 447 | System.out.println("contains(6): " + list.contains(6)); 448 | 449 | System.out.println(); 450 | 451 | System.out.println("remove(3): " + list.remove(3)); 452 | System.out.println("items: " + list); 453 | System.out.println("size: " + list.size()); 454 | 455 | System.out.println(); 456 | 457 | System.out.println("remove(10): " + list.remove(10)); 458 | System.out.println("items: " + list); 459 | System.out.println("size: " + list.size()); 460 | 461 | System.out.println(); 462 | 463 | System.out.println("add(60)"); 464 | list.add(60); 465 | System.out.println("add(60)"); 466 | list.add(60); 467 | System.out.println("add(60)"); 468 | list.add(60); 469 | System.out.println("add(70)"); 470 | list.add(70); 471 | 472 | System.out.println("add(6)"); 473 | list.add(6); 474 | System.out.println("add(22)"); 475 | list.add(22); 476 | System.out.println("add(38)"); 477 | list.add(38); 478 | 479 | System.out.println("items: " + list); 480 | System.out.println("size: " + list.size()); 481 | 482 | System.out.println(); 483 | 484 | System.out.println("contains(60): " + list.contains(60)); 485 | System.out.println("remove(60): " + list.remove(60)); 486 | System.out.println("contains(60): " + list.contains(60)); 487 | 488 | 489 | System.out.println("items: " + list); 490 | System.out.println("size: " + list.size()); 491 | 492 | System.out.println(); 493 | 494 | System.out.println("contains(22): " + list.contains(22)); 495 | System.out.println("remove(22): " + list.remove(22)); 496 | System.out.println("contains(22): " + list.contains(22)); 497 | 498 | System.out.println(); 499 | 500 | System.out.println("items: " + list); 501 | System.out.println("size: " + list.size()); 502 | */ 503 | } 504 | } 505 | -------------------------------------------------------------------------------- /List/ArrayList.java: -------------------------------------------------------------------------------- 1 | package list; 2 | 3 | public class ArrayList { 4 | 5 | private static int CAPACITY = 10; 6 | private T[] arr = (T[]) new Object[CAPACITY]; 7 | private int size = 0; 8 | 9 | public ArrayList() { } 10 | 11 | public int size() { 12 | return size; 13 | } 14 | public boolean isEmpty() { 15 | return size==0; 16 | } 17 | public void add(T item) { 18 | if(size==CAPACITY) resize(); 19 | arr[size++] = item; 20 | } 21 | private boolean resize() { 22 | int temp = CAPACITY; 23 | CAPACITY = CAPACITY<<1; 24 | T[] arrCopy = arr; 25 | arr = (T[]) new Object[CAPACITY]; 26 | for(int i=0; i=size) throw new ArrayIndexOutOfBoundsException(); 34 | T res = arr[index]; 35 | for(int i=index; i=CAPACITY) throw new ArrayIndexOutOfBoundsException(); 44 | return arr[index]; 45 | } 46 | 47 | public String toString() { 48 | StringBuilder sb = new StringBuilder(); 49 | for(int i=0; i list = new ArrayList<>(); 58 | 59 | System.out.println("add(0)"); 60 | list.add(0); 61 | System.out.println("add(10)"); 62 | list.add(10); 63 | System.out.println("add(20)"); 64 | list.add(20); 65 | System.out.println("add(30)"); 66 | list.add(30); 67 | System.out.println("add(40)"); 68 | list.add(40); 69 | System.out.println("add(50)"); 70 | list.add(50); 71 | 72 | System.out.println("items: " + list); 73 | System.out.println("size: " + list.size()); 74 | System.out.println("get(0): " + list.get(0)); 75 | System.out.println("get(1): " + list.get(1)); 76 | System.out.println("get(2): " + list.get(2)); 77 | System.out.println("get(5): " + list.get(5)); 78 | 79 | System.out.println(); 80 | 81 | System.out.println("remove(3): " + list.remove(3)); 82 | System.out.println("items: " + list); 83 | System.out.println("size: " + list.size()); 84 | 85 | System.out.println(); 86 | 87 | System.out.println("remove(3): " + list.remove(3)); 88 | System.out.println("items: " + list); 89 | System.out.println("size: " + list.size()); 90 | 91 | System.out.println(); 92 | 93 | 94 | System.out.println("remove(3): " + list.remove(3)); 95 | System.out.println("items: " + list); 96 | System.out.println("size: " + list.size()); 97 | 98 | System.out.println(); 99 | 100 | System.out.println("add(60)"); 101 | list.add(60); 102 | System.out.println("add(70)"); 103 | list.add(70); 104 | 105 | System.out.println("items: " + list); 106 | System.out.println("size: " + list.size()); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /List/LinkedList/DList.java: -------------------------------------------------------------------------------- 1 | package list; 2 | public class DList { 3 | private int size; 4 | public DListNode head; 5 | 6 | // construct an empty DList 7 | public DList() { 8 | size = 0; 9 | head = new DListNode(1); 10 | head.next = head; 11 | head.prev = head; 12 | } 13 | // construct a DList with one item 14 | public DList(int i) { 15 | head = new DListNode(1); 16 | DListNode first = new DListNode(i); 17 | head.next = first; 18 | head.prev = first; 19 | first.next = head; 20 | first.prev = head; 21 | size = 1; 22 | } 23 | // construct a DList with one item 24 | public DList(DListNode node) { 25 | head = new DListNode(1); 26 | head.next = node; 27 | head.prev = node; 28 | node.next = head; 29 | node.prev = head; 30 | size = 1; 31 | } 32 | 33 | // get size 34 | public int size() { 35 | return size; 36 | } 37 | public int length() { 38 | return size; 39 | } 40 | 41 | // check whether empty 42 | public boolean isEmpty() { 43 | return size==0; 44 | } 45 | 46 | // get first node 47 | public DListNode first() { 48 | if(size==0) return null; // return null if DList is empty 49 | return head.next; 50 | } 51 | // get last node 52 | public DListNode last() { 53 | if(size==0) return null; // return null if DList is empty 54 | return head.prev; 55 | } 56 | 57 | // insert a new node after the head 58 | public void insertAfterHead(DListNode node) { 59 | head.next.prev = node; // set the head's next node's prev pointer to input node 60 | node.next = head.next; // set new node's next pointer to head's next node 61 | head.next = node; // set head's next pointer to new node 62 | node.prev = head; // set node's prev pointer to head 63 | size++; 64 | } 65 | // insert a new node before the head 66 | public void insertBeforeHead(DListNode node) { 67 | head.prev.next = node; // set the head's prev node's next pointer to input node 68 | node.prev = head.prev; // set new node's prev pointer to head's prev node 69 | head.prev = node; // set head's prev pointer to new node 70 | node.next = head; // set node's next pointer to head 71 | size++; 72 | } 73 | 74 | // insert item right after node if node is not null, otherwise do nothing 75 | public void insertAfter(int i, DListNode node) { 76 | if(node==null) return; 77 | if(node.next==null) return; // if node is not attached to a DList, do nothing? 78 | DListNode newNode = new DListNode(i); 79 | node.next.prev = newNode; 80 | newNode.next = node.next; 81 | node.next = newNode; 82 | newNode.prev = node; 83 | size++; 84 | } 85 | // insert item right before node if node is not null, otherwise do nothing 86 | public void insertBefore(int i, DListNode node) { 87 | if(node==null) return; 88 | if(node.prev==null) return; // if node is not attached to a DList, do nothing? 89 | DListNode newNode = new DListNode(i); 90 | node.prev.next = newNode; 91 | newNode.prev = node.prev; 92 | newNode.next = node; 93 | node.prev = newNode; 94 | size++; 95 | } 96 | 97 | // remove a specific node from the List. If node is null, do nothing. If node's next pointer is null, do nothing as well. 98 | public void remove(DListNode node) { 99 | if(node==null) return; 100 | if(node.next==null) return; 101 | 102 | node.prev.next = node.next; 103 | node.next.prev = node.prev; 104 | size--; 105 | } 106 | 107 | // convert DList contents to string for display 108 | public String toString() { 109 | String str = "head<==>"; 110 | DListNode current = head.next; 111 | int L = size; 112 | while(L>=1) { 113 | str += current.val + "<==>"; 114 | current = current.next; 115 | L--; 116 | } 117 | str += "head"; 118 | return str; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /List/LinkedList/DListDriver.java: -------------------------------------------------------------------------------- 1 | package list; 2 | 3 | public class DriverDList { 4 | public static void main(String[] args) { 5 | 6 | DList head = new DList(); // empty list: head<==>head 7 | head.insertAfterHead(new DListNode(3)); // current list: head<==3<==>head 8 | head.insertBeforeHead(new DListNode(200)); // current list: head<==3<==>200<==>head 9 | head.insertAfterHead(new DListNode(5)); // current list: head<==5<==>3<==>200<==>head 10 | head.insertBeforeHead(new DListNode(100)); // current list: head<==5<==>3<==>200<==>100<==>head 11 | System.out.println("L1: " + head.toString()); // expected output: head<==>5<==>3<==>200<==>100<==>head 12 | 13 | DListNode node1 = new DListNode(222); 14 | head.insertAfterHead(node1); // current list: head<==222<==>5<==>3<==>200<==>100<==>head 15 | System.out.println("L2: " + head.toString()); // expected output: head<==222<==>5<==>3<==>200<==>100<==>head 16 | DListNode node2 = new DListNode(345); 17 | head.insertBeforeHead(node2); // current list: head<==222<==>5<==>3<==>200<==>100<==>345<==>head 18 | System.out.println("L3: " + head.toString()); // expected output: head<==222<==>5<==>3<==>200<==>100<==>345<==>head 19 | 20 | head.insertAfter(10, node1); // current list: head<==222<==>10<==>5<==>3<==>200<==>100<==>345<==>head 21 | head.insertBefore(66, node2); // current list: head<==222<==>10<==>5<==>3<==>200<==>100<==>66<==>345<==>head 22 | System.out.println("L4: " + head.toString()); // expected output: head<==222<==>10<==>5<==>3<==>200<==>100<==>66<==>345<==>head 23 | 24 | head.remove(new DListNode()); // will do nothing 25 | System.out.println("L5: " + head.toString()); // expected output: head<==222<==>10<==>5<==>3<==>200<==>100<==>66<==>345<==>head 26 | head.remove(node1); // current list: head<==10<==>5<==>3<==>200<==>100<==>66<==>345<==>head 27 | System.out.println("L6: " + head.toString()); // expected output: head<==10<==>5<==>3<==>200<==>100<==>66<==>345<==>head 28 | 29 | System.out.println("List size:" + head.size()); // current size: 7 30 | System.out.println("First node value: " + head.first().val); // first node value: 10 31 | System.out.println("Last node value: " + head.last().val); // last node value: 345 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /List/LinkedList/DListNode.java: -------------------------------------------------------------------------------- 1 | package list; 2 | import java.util.NoSuchElementException; 3 | 4 | public class DListNode { 5 | public int val; 6 | public DListNode next; 7 | public DListNode prev; 8 | 9 | public DListNode() { 10 | val = 0; 11 | next = null; 12 | prev = null; 13 | } 14 | public DListNode(int i) { 15 | val = i; 16 | next = null; 17 | prev = null; 18 | } 19 | public DListNode(int i, DListNode next, DListNode prev) { 20 | val = i; 21 | this.next = next; 22 | this.prev = prev; 23 | } 24 | 25 | // insert a node after a specific node 26 | public void insertAfter(DListNode node) { 27 | node.next = this.next; 28 | if(this.next!=null) 29 | this.next.prev = node; 30 | 31 | this.next = node; 32 | node.prev = this; 33 | } 34 | 35 | // remove a specified node 36 | public void removeNode() { 37 | if( this.next==null && this.prev!=null ) { 38 | this.prev.next = null; 39 | } 40 | else if( this.next!=null && this.prev==null ) { 41 | this.next.prev = null; 42 | } 43 | else if( this.next!=null && this.prev!=null ) { 44 | this.prev.next = this.next; 45 | this.next.prev = this.prev; 46 | } 47 | else { 48 | throw new NoSuchElementException("Null node!"); 49 | } 50 | } 51 | 52 | public String toString() { 53 | String str = "null<=="; 54 | DListNode head = this; 55 | while(head != null) { 56 | str += head.val + "<==>"; 57 | head = head.next; 58 | } 59 | str = str.substring(0,str.length()-4) + "==>null"; 60 | 61 | return str; 62 | } 63 | 64 | public static void main(String[] args) { 65 | DListNode head = new DListNode(); 66 | DListNode current = head; 67 | for(int i=1; i<=10; i++) { 68 | DListNode newNode = new DListNode(i*i); 69 | current.next = newNode; 70 | newNode.prev = current; 71 | current = newNode; 72 | } 73 | System.out.println(head.toString()); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /List/Stack.java: -------------------------------------------------------------------------------- 1 | package stack; 2 | import java.util.Iterator; 3 | import java.util.NoSuchElementException; 4 | 5 | /** 6 | * A LIFO stack of generic types 7 | * 8 | * @author FLAG 9 | * @param generic type of the stack item 10 | */ 11 | 12 | public class Stack implements Iterable { 13 | private int size; 14 | private SListNode head; 15 | 16 | private class SListNode { 17 | public Type2 val; 18 | public SListNode next; 19 | 20 | public SListNode(Type2 i) { 21 | this.val = i; 22 | this.next = null; 23 | } 24 | } 25 | 26 | public Stack() { 27 | head = null; 28 | size = 0; 29 | } 30 | 31 | public int size() { 32 | //if(size==0) throw new NoSuchElementException("Stack empty!"); 33 | return size; 34 | } 35 | 36 | public boolean isEmpty() { 37 | return size==0; 38 | } 39 | 40 | public Type push(Type item) { 41 | SListNode newHead = new SListNode<>(item); 42 | newHead.next = head; 43 | head = newHead; 44 | ++size; 45 | return item; 46 | } 47 | 48 | public Type pop() { 49 | if(size==0) throw new NoSuchElementException("Stack empty!"); 50 | Type res = head.val; 51 | SListNode newHead = head.next; 52 | head = newHead; 53 | --size; 54 | return res; 55 | } 56 | 57 | public Type peek() { 58 | if(size==0) throw new NoSuchElementException("Stack empty!"); 59 | return head.val; 60 | } 61 | 62 | public Iterator iterator() { 63 | return new ListIterator(head); 64 | } 65 | private class ListIterator implements Iterator { 66 | private SListNode current; 67 | 68 | public ListIterator(SListNode current) { 69 | this.current = current; 70 | } 71 | 72 | public boolean hasNext() { 73 | return current != null; 74 | } 75 | 76 | public Type3 next() { 77 | if (!hasNext()) throw new NoSuchElementException("No next element!"); 78 | Type3 val = current.val; 79 | current = current.next; 80 | return val; 81 | } 82 | } 83 | 84 | public String toString() { 85 | String str = ""; 86 | SListNode current = head; 87 | while(current!=null) { 88 | str += current.val + "-->"; 89 | current = current.next; 90 | } 91 | str += "null"; 92 | return str; 93 | } 94 | 95 | public static void main(String[] args) { 96 | 97 | Stack stack = new Stack<>(); 98 | 99 | System.out.println("stack size: " + stack.size() + "\n"); 100 | 101 | stack.push('i'); 102 | stack.push('h'); 103 | stack.push('g'); 104 | stack.push('f'); 105 | System.out.println("stack: " + stack.toString()); 106 | System.out.println("stack size: " + stack.size() + "\n"); 107 | 108 | stack.push('e'); 109 | stack.push('d'); 110 | stack.pop(); 111 | stack.push('c'); 112 | stack.push('b'); 113 | System.out.println("stack: " + stack.toString()); 114 | System.out.println("stack peek: " + stack.peek()); 115 | System.out.println("stack size: " + stack.size() + "\n"); 116 | 117 | stack.pop(); 118 | System.out.println("stack: " + stack.toString()); 119 | System.out.println("stack peek: " + stack.peek() + "\n"); 120 | 121 | stack.push('a'); 122 | System.out.println("stack: " + stack.toString()); 123 | System.out.println("stack size: " + stack.size() + "\n"); 124 | 125 | Iterator it = stack.iterator(); 126 | System.out.print("iterator: "); 127 | while(it.hasNext()) { 128 | System.out.print(it.next() + "-->"); 129 | } 130 | System.out.print("null\n\n"); 131 | 132 | stack.pop(); 133 | stack.pop(); 134 | stack.pop(); 135 | stack.pop(); 136 | stack.pop(); 137 | stack.pop(); 138 | System.out.println("stack peek: " + stack.peek()); 139 | System.out.println("stack: " + stack.toString()); 140 | System.out.println("stack size: " + stack.size() + "\n"); 141 | 142 | /* 143 | stack.pop(); 144 | System.out.println("print exception: "); 145 | stack.pop(); 146 | */ 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures in Java 2 | 3 | my own implementation of basic data structures in java. 4 | 5 | Data structures already uploaded: 6 | Double linked list 7 | 8 | Data structures to be uploaded: 9 | Single linked list 10 | Stack 11 | Queue 12 | Binary search tree 13 | -------------------------------------------------------------------------------- /Tree/BST.java: -------------------------------------------------------------------------------- 1 | import java.util.NoSuchElementException; 2 | 3 | 4 | public class BST { 5 | private int size = 0; 6 | private Node head; 7 | 8 | protected class Node { 9 | int val; 10 | Node left; 11 | Node right; 12 | Node parent; 13 | 14 | public Node(int i) { 15 | val = i; 16 | } 17 | } 18 | 19 | public BST() { 20 | 21 | } 22 | public BST(int i) { 23 | head = new Node(i); 24 | size = 1; 25 | //depth = 0; 26 | //levelNodes[0] = 1; 27 | } 28 | 29 | public int size() { 30 | return size; 31 | } 32 | public int length() { 33 | return size; 34 | } 35 | 36 | // get depth 37 | public int depth() { 38 | return getSubDepth(head); 39 | } 40 | // recursive method to get depth of any subtree 41 | private int getSubDepth(Node node) { 42 | if(node == null) return -1; 43 | //System.out.println("Current node: " + subBST.val); 44 | return 1 + (getSubDepth(node.left) >= getSubDepth(node.right) 45 | ? getSubDepth(node.left) 46 | : getSubDepth(node.right)); 47 | } 48 | 49 | public void add(int newItem) { 50 | if(size == 0) { 51 | head = new Node(newItem); 52 | } 53 | else { 54 | //int level = 0; // the current level 55 | double d; // to be used to randomly choose left or right subtree 56 | Node current = head; 57 | Node newNode = new Node(newItem); 58 | while(current != null) { 59 | //level++; // level increased by one 60 | // go to left subtree if new item is less than current node key 61 | if(current.val > newItem) { 62 | // add the node to its current left if current lefft is empty 63 | if(current.left == null) { 64 | current.left = newNode; 65 | newNode.parent = current; 66 | break; 67 | } 68 | // go to its left subtree 69 | else 70 | current = current.left; 71 | } 72 | // go to right subtree if new item is greater than current node key 73 | else if(current.val < newItem) { 74 | if(current.right == null) { 75 | current.right = newNode; 76 | newNode.parent = current; 77 | break; 78 | } 79 | else 80 | current = current.right; 81 | } 82 | // when new item is the same as the current node key 83 | else { 84 | // add to its left subtree of current left subtree is empty 85 | if(current.left == null) { 86 | current.left = newNode; 87 | newNode.parent = current; 88 | break; 89 | } 90 | // add to its right subtree of current right subtree is empty 91 | else if(current.right == null) { 92 | current.right = newNode; 93 | newNode.parent = current; 94 | break; 95 | } 96 | // when neither left or right subtree is empty, randomly choose left or right subtree 97 | else { 98 | d = Math.random(); 99 | //System.out.println("current node's key = new item; randomly choose " + (d>0.5 ? "left":"right") ); 100 | current = (d>0.5) ? current.left:current.right; 101 | } 102 | } 103 | } 104 | 105 | //System.out.println(newItem + " added at level " + level); 106 | } 107 | 108 | size++; 109 | } 110 | 111 | public void remove(int newItem) { 112 | if(size == 0) throw new NoSuchElementException("empty tree!"); 113 | else if(size==1) { 114 | if(head.val == newItem) { 115 | head = null; 116 | size = 0; 117 | } 118 | else 119 | return; 120 | } 121 | Node current = head; 122 | while(current != null) { 123 | if(current.val < newItem) { 124 | current = current.right; 125 | } 126 | else if(current.val > newItem) 127 | current = current.left; 128 | else { 129 | size--; // reduce size; 130 | // current node has no child, just remove it 131 | if(current.left==null && current.right==null) { 132 | if(current.parent.val <= current.val) 133 | current.parent.right = null; 134 | else 135 | current.parent.left = null; 136 | break; 137 | } 138 | // current node has only a right node, move right node up to current 139 | else if(current.left == null) { 140 | current.parent.left = current.right; // = current.right; 141 | break; 142 | } 143 | // current node has only a left node, move left node up to current 144 | else if(current.right == null) { 145 | current.parent.right = current.left; 146 | break; 147 | } 148 | // current node has two children, find the smallest key greater than current node, move that key to current node 149 | else { 150 | Node node = current.right; 151 | Node p = current; 152 | while(node != null) { 153 | p = node; 154 | node = node.left; 155 | } 156 | int replace = p.val; 157 | p.parent.left = null; 158 | current.val = replace; 159 | } 160 | } 161 | } 162 | } 163 | 164 | public int max() { 165 | if(size == 0) throw new NoSuchElementException("Empty tree!"); 166 | int max = head.val; 167 | Node current = head; 168 | while(current.right != null) { 169 | current = current.right; 170 | max = current.val; 171 | } 172 | return max; 173 | } 174 | public int min() { 175 | if(size == 0) throw new NoSuchElementException("Empty tree!"); 176 | int min = head.val; 177 | Node current = head; 178 | while(current.left != null) { 179 | current = current.left; 180 | min = current.val; 181 | } 182 | return min; 183 | } 184 | 185 | public int search(int target) { 186 | if(size == 0) throw new NoSuchElementException("Empty tree!"); 187 | 188 | int level = 0; 189 | Node current = head; 190 | while(current != null) { 191 | if(current.val == target) 192 | return level; 193 | else if(current.val < target) 194 | current = current.right; 195 | else 196 | current = current.left; 197 | level++; 198 | } 199 | return -1; 200 | } 201 | 202 | // find the node whose key is the minimal of those greater than target 203 | public void closest(int target) { 204 | if(size == 0) throw new NoSuchElementException("Empty tree!"); 205 | 206 | int[] arr = new int[2]; 207 | boolean existNextLarge, existNextSmall; 208 | existNextLarge = existNextSmall = false; 209 | 210 | Node current = head; 211 | while(current != null) { 212 | if(current.val == target) { 213 | System.out.println(target + " is in the tree."); 214 | } 215 | else if(current.val < target) { 216 | arr[1] = (!existNextSmall) ? current.val : (arr[0]>current.val ? current.val : arr[1]); 217 | current = current.right; 218 | existNextSmall = true; 219 | } 220 | else { 221 | arr[0] = (!existNextLarge) ? current.val : (arr[0]>current.val ? current.val : arr[0]); 222 | current = current.left; 223 | existNextLarge = true; 224 | } 225 | } 226 | if(existNextLarge) 227 | System.out.print("Next greater key: " + arr[0] + "; "); 228 | else 229 | System.out.print("Next greater key: na; "); 230 | if(existNextSmall) 231 | System.out.print("Next smaller key: " + arr[1] + "."); 232 | else 233 | System.out.print("Next smaller key: na."); 234 | } 235 | 236 | /* 237 | public String toString() { 238 | String str = ""; 239 | BST current = this; 240 | while(current != null) { 241 | str += nodeToString(current); 242 | BST currentLeft = current.left; 243 | BST currentRight = current.right; 244 | while(currentLeft != null) 245 | str += nodeToString(currentLeft); 246 | while(currentRight != null) 247 | str += nodeToString(currentRight); 248 | } 249 | return str; 250 | } 251 | private String getString(BST subBST) { 252 | while(subBST != null) { 253 | str += nodeToString(subBST); 254 | } 255 | } 256 | private String nodeToString(BST subBST) { 257 | if(subBST == null) return ""; 258 | 259 | return subBST.val + ":" + (subBST.left!=null?subBST.left.val:" ") + "\t" + (subBST.right!=null?subBST.right.val:" ") + "\n"; 260 | //return subBST.val + ":" + nodeToString(subBST.left) + "\t" + nodeToString(subBST.right); 261 | } 262 | */ 263 | public static void main(String[] args) { 264 | 265 | BST head = new BST(); 266 | head.add(15); 267 | head.add(30); 268 | head.add(0); 269 | head.add(7); 270 | head.add(40); 271 | head.add(25); 272 | head.add(4); 273 | head.add(10); 274 | head.add(-5); 275 | head.add(7); 276 | head.add(7); 277 | head.add(7); 278 | head.add(7); 279 | head.add(7); 280 | //head.add(35); 281 | //head.add(30); 282 | System.out.println("Tree size: " + head.size()); 283 | System.out.println("Max value: " + head.max()); 284 | System.out.println("Min value: " + head.min()); 285 | System.out.println("Tree depth: " + head.depth()); 286 | head.closest(8); 287 | //System.out.println("Tree:\n" + head.toString()); 288 | 289 | /* 290 | System.out.println("search 10:" + head.search(10)); 291 | System.out.println("search 23: " + head.search(23)); 292 | head.remove(23); 293 | head.remove(7); 294 | head.remove(25); 295 | head.remove(40); 296 | head.remove(15); 297 | head.remove(15); 298 | head.remove(7); 299 | head.remove(40); 300 | head.remove(25); 301 | head.remove(30); 302 | head.remove(0); 303 | head.remove(23); 304 | head.remove(23); 305 | //head.remove(15); 306 | //head.remove(23); 307 | System.out.println("search for 15: " + head.search(15)); 308 | System.out.println("Tree depth: (method): " + head.depth()); 309 | System.out.println("size: " + head.size()); 310 | System.out.println("Max value: " + head.max()); 311 | System.out.println("Min value: " + head.min()); 312 | */ 313 | 314 | /* 315 | //Test running time of getDepth() 316 | BST head = new BST(10); 317 | int N; 318 | System.out.println("N\tElapsed Time"); 319 | for(int j=1; j<20; j++) { 320 | N = (int)Math.pow(2, j); 321 | for(int i=0; i generic type of data stored in tree node 8 | */ 9 | 10 | 11 | public class RedBlackTree> implements Comparable { 12 | public static final boolean RED = true; 13 | public static final boolean BLACK = false; 14 | 15 | private Node root; 16 | private int size; 17 | 18 | 19 | private class Node { 20 | private Type2 val; 21 | private Node left, right; 22 | private boolean color; 23 | 24 | public Node(Type2 val, boolean color) { 25 | this.val = val; 26 | this.color = color; 27 | } 28 | } 29 | 30 | public RedBlackTree() { 31 | size = 0; 32 | root = null; 33 | } 34 | 35 | @Override 36 | public int compareTo(Type val) { 37 | return root.val.compareTo(val); 38 | } 39 | 40 | 41 | public Node get(Type target) { 42 | return get(root, target); 43 | } 44 | private Node get(Node root, Type target) { 45 | while(root!=null) { 46 | if(root.val==target) return root; 47 | else if(root.val.compareTo(target)>0) root = root.left; 48 | else root = root.right; 49 | } 50 | return null; 51 | } 52 | 53 | public boolean contains(Type target) { 54 | return get(target)!=null; 55 | } 56 | 57 | public void put(Type newValue) { 58 | root = put(root, newValue); 59 | root.color = BLACK; 60 | } 61 | 62 | private Node put(Node root, Type newValue) { 63 | if(root==null) { 64 | size++; 65 | return new Node(newValue, RED); 66 | } 67 | 68 | if(root.val.compareTo(newValue)>0) root.left = put(root.left, newValue); 69 | else if(root.val.compareTo(newValue)<0) root.right = put(root.right, newValue); 70 | else return root; 71 | 72 | 73 | if(isRed(root.right) && !isRed(root.left)) root = rotateLeft(root); 74 | if(isRed(root.left) && isRed(root.left.left)) root = rotateRight(root); 75 | if(isRed(root.left) && isRed(root.right)) flipColor(root); 76 | 77 | return root; 78 | } 79 | 80 | 81 | public boolean isRed(Node node) { 82 | return (node==null) ? false : node.color==RED; 83 | } 84 | 85 | public Node rotateLeft(Node node) { 86 | assert(node!=null); 87 | Node x = node.right; 88 | assert(isRed(x)); 89 | node.right = x.left; 90 | x.left = node; 91 | x.color = node.color; 92 | node.color = RED; 93 | return x; 94 | } 95 | public Node rotateRight(Node node) { 96 | assert(node!=null); 97 | Node x = node.left; 98 | assert(isRed(x)); 99 | assert(isRed(x.left)); 100 | node.left = x.right; 101 | x.right = node; 102 | x.color = node.color; 103 | node.color = RED; 104 | return x; 105 | } 106 | public void flipColor(Node node) { 107 | node.color = !node.color; 108 | node.left.color = !node.left.color; 109 | node.right.color = !node.right.color; 110 | } 111 | 112 | 113 | public int size() { 114 | return size; 115 | } 116 | public boolean isEmpty() { 117 | return size==0; 118 | } 119 | public int height() { 120 | return height(root); 121 | } 122 | private int height(Node root) { 123 | if(root==null) return 0; 124 | int height = Math.max(height(root.left), height(root.right)) + 1; 125 | if(isRed(root)) height--; 126 | return height; 127 | } 128 | 129 | 130 | public void inorder() { 131 | inorder(root); 132 | } 133 | private void inorder(Node root) { 134 | if(root==null) return; 135 | inorder(root.left); 136 | System.out.print(root.val + " "); 137 | inorder(root.right); 138 | } 139 | 140 | public void preorder() { 141 | preorder(root); 142 | } 143 | private void preorder(Node root) { 144 | if(root==null) return; 145 | System.out.print(root.val + " "); 146 | preorder(root.left); 147 | preorder(root.right); 148 | } 149 | 150 | public void postorder() { 151 | postorder(root); 152 | } 153 | private void postorder(Node root) { 154 | if(root==null) return; 155 | postorder(root.left); 156 | postorder(root.right); 157 | System.out.print(root.val + " "); 158 | } 159 | 160 | // reference: http://stackoverflow.com/questions/4965335/how-to-print-binary-tree-diagram#answer-27153988 161 | public String toString() { 162 | return toString(root, new StringBuffer(), true, new StringBuffer()).toString(); 163 | } 164 | public StringBuffer toString(Node root, StringBuffer prefix, boolean isTail, StringBuffer sb) { 165 | if(root.right!=null) { 166 | toString(root.right, new StringBuffer().append(prefix).append(isTail ? "│ " : " "), false, sb); 167 | } 168 | String str = root.color ? "*" + root.val + "*" : " " + root.val + " "; 169 | sb.append(prefix).append(isTail ? "└──" : "┌──").append(str).append("\n"); 170 | if(root.left!=null) { 171 | toString(root.left, new StringBuffer().append(prefix).append(isTail ? " " : "│ "), true, sb); 172 | } 173 | return sb; 174 | } 175 | 176 | public static void main(String[] args) { 177 | RedBlackTree tree = new RedBlackTree(); 178 | 179 | tree.put('s'); 180 | 181 | System.out.println("----------------------"); 182 | System.out.println("\tput s\t"); 183 | System.out.println("----------------------"); 184 | System.out.println("\ntree content (** indicates a red node): "); 185 | System.out.println(tree.toString() + "\n"); 186 | 187 | tree.put('e'); 188 | 189 | System.out.println("----------------------"); 190 | System.out.println("\tput e\t"); 191 | System.out.println("----------------------"); 192 | System.out.println("\ntree content (** indicates a red node): "); 193 | System.out.println(tree.toString() + "\n"); 194 | 195 | tree.put('a'); 196 | 197 | System.out.println("----------------------"); 198 | System.out.println("\tput a\t"); 199 | System.out.println("----------------------"); 200 | System.out.println("\ntree content (** indicates a red node): "); 201 | System.out.println(tree.toString() + "\n"); 202 | 203 | tree.put('r'); 204 | 205 | System.out.println("----------------------"); 206 | System.out.println("\tput r\t"); 207 | System.out.println("----------------------"); 208 | System.out.println("\ntree content (** indicates a red node): "); 209 | System.out.println(tree.toString() + "\n"); 210 | 211 | tree.put('c'); 212 | 213 | System.out.println("----------------------"); 214 | System.out.println("\tput c\t"); 215 | System.out.println("----------------------"); 216 | System.out.println("\ntree content (** indicates a red node): "); 217 | System.out.println(tree.toString() + "\n"); 218 | 219 | tree.put('h'); 220 | 221 | System.out.println("----------------------"); 222 | System.out.println("\tput h\t"); 223 | System.out.println("----------------------"); 224 | System.out.println("\ntree content (** indicates a red node): "); 225 | System.out.println(tree.toString() + "\n"); 226 | 227 | tree.put('x'); 228 | 229 | System.out.println("----------------------"); 230 | System.out.println("\tput x\t"); 231 | System.out.println("----------------------"); 232 | System.out.println("\ntree content (** indicates a red node): "); 233 | System.out.println(tree.toString() + "\n"); 234 | 235 | tree.put('m'); 236 | 237 | System.out.println("----------------------"); 238 | System.out.println("\tput m\t"); 239 | System.out.println("----------------------"); 240 | System.out.println("\ntree content (** indicates a red node): "); 241 | System.out.println(tree.toString() + "\n"); 242 | 243 | tree.put('p'); 244 | 245 | System.out.println("----------------------"); 246 | System.out.println("\tput p\t"); 247 | System.out.println("----------------------"); 248 | System.out.println("\ntree content (** indicates a red node): "); 249 | System.out.println(tree.toString() + "\n"); 250 | 251 | tree.put('l'); 252 | 253 | System.out.println("----------------------"); 254 | System.out.println("\tput l\t"); 255 | System.out.println("----------------------"); 256 | System.out.println("\ntree content (** indicates a red node): "); 257 | System.out.println(tree.toString() + "\n"); 258 | 259 | System.out.println("\ntree content (** indicates a red node): "); 260 | System.out.println(tree.toString() + "\n"); 261 | 262 | System.out.println("tree size: " + tree.size()); 263 | System.out.println("tree height: " + tree.height()); 264 | System.out.println("contains 's'? " + tree.contains('s')); 265 | System.out.println("contains 't'? " + tree.contains('t')); 266 | System.out.println("contains 'b'? " + tree.contains('b')); 267 | 268 | System.out.println(); 269 | 270 | tree.put('t'); 271 | 272 | System.out.println("----------------------"); 273 | System.out.println("\tput t\t"); 274 | System.out.println("----------------------"); 275 | 276 | System.out.println("\ntree content (** indicates a red node): "); 277 | System.out.println(tree.toString() + "\n"); 278 | 279 | tree.put('y'); 280 | 281 | System.out.println("----------------------"); 282 | System.out.println("\tput y\t"); 283 | System.out.println("----------------------"); 284 | 285 | System.out.println("\ntree content (** indicates a red node): "); 286 | System.out.println(tree.toString() + "\n"); 287 | 288 | tree.put('w'); 289 | 290 | System.out.println("----------------------"); 291 | System.out.println("\tput w\t"); 292 | System.out.println("----------------------"); 293 | 294 | System.out.println("\ntree content (** indicates a red node): "); 295 | System.out.println(tree.toString() + "\n"); 296 | 297 | System.out.println("tree size: " + tree.size()); 298 | System.out.println("tree height: " + tree.height()); 299 | System.out.println("contains 's'? " + tree.contains('s')); 300 | System.out.println("contains 't'? " + tree.contains('t')); 301 | System.out.println("contains 'b'? " + tree.contains('b')); 302 | 303 | System.out.println(); 304 | 305 | System.out.print("inorder traversal\t: "); 306 | tree.inorder(); 307 | System.out.print("\npreorder traversal\t: "); 308 | tree.preorder(); 309 | System.out.print("\npostorder traversal\t: "); 310 | tree.postorder(); 311 | System.out.println(); 312 | 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /Tree/Trie.java: -------------------------------------------------------------------------------- 1 | package trie; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * implements a trie that stores strings/words consisted of ASCII characters 8 | * 9 | * implemented methods include: 10 | * - insert word into trie 11 | * - search for a word 12 | * - search for a prefix 13 | * - print trie content following trie format 14 | * - list all words in trie 15 | * 16 | * @author FLAG 17 | */ 18 | 19 | public class Trie { 20 | private static final int R = 256; // extended ASCII 21 | private TrieNode root; 22 | 23 | private class TrieNode { 24 | boolean isEnd; 25 | TrieNode[] children; 26 | 27 | public TrieNode() { 28 | isEnd = true; 29 | children = new TrieNode[R]; 30 | } 31 | } 32 | 33 | public Trie() { 34 | root = new TrieNode(); 35 | } 36 | 37 | // Inserts a word into the trie. 38 | public void insert(String word) { 39 | TrieNode current = root; 40 | for(int i=0, L=word.length(); i listWords() { 74 | List list = new ArrayList<>(); 75 | list(root, 0, "", list); 76 | return list; 77 | } 78 | private void list(TrieNode current, int id, String prefix, List list) { 79 | if(current==null) return; 80 | for(int i=0; i=0; i--) { 105 | if(root.children[i]!=null) { 106 | if(isLastChild) { 107 | isLastChild = false; 108 | lastChild = root.children[i]; 109 | lastChildId = i; 110 | } 111 | else print(prefix + (isRoot ? "" : (isTail ? " " : "│ ")), root.children[i], i, false, false); 112 | } 113 | } 114 | if (lastChild!=null) { 115 | print(prefix + (isRoot ? "" : (isTail ?" " : "│ ")), lastChild, lastChildId, true, false); 116 | } 117 | } 118 | 119 | public static void main(String[] args) { 120 | Trie trie = new Trie(); 121 | trie.insert("abc"); 122 | trie.insert("bay"); 123 | trie.insert("bey"); 124 | trie.insert("bea"); 125 | trie.insert("bed"); 126 | trie.insert("bee"); 127 | trie.insert("boy"); 128 | trie.insert("boyc"); 129 | trie.insert("boyd"); 130 | trie.insert("boye"); 131 | trie.insert("boycd"); 132 | trie.insert("bye-bye"); 133 | trie.insert("by-by"); 134 | trie.insert("bye"); 135 | trie.insert("zad"); 136 | trie.insert("zed"); 137 | trie.insert("zef"); 138 | 139 | System.out.println("trie content (*** indicates the end of a word): "); 140 | trie.print(); 141 | System.out.println(); 142 | 143 | System.out.println("list of words in trie: "); 144 | System.out.println(trie.listWords()); 145 | System.out.println(); 146 | 147 | System.out.println("contains boy? " + trie.contains("boy")); 148 | System.out.println("contains bo? " + trie.contains("bo")); 149 | System.out.println("contains boye? " + trie.contains("boye")); 150 | System.out.println("contains byebye? " + trie.contains("byebye")); 151 | System.out.println("contains bye-bye? " + trie.contains("bye-bye")); 152 | 153 | System.out.println(); 154 | 155 | System.out.println("contains prefix bo? " + trie.containsPrefix("bo")); 156 | System.out.println("contains prefix b o? " + trie.containsPrefix("b o")); 157 | System.out.println("contains prefix bye? " + trie.containsPrefix("bye")); 158 | System.out.println("contains prefix ye? " + trie.containsPrefix("ye")); 159 | 160 | 161 | /* 162 | expected output: 163 | trie content (*** indicates the end of a word): 164 | ├── b 165 | │ ├── o 166 | │ │ └── y *** 167 | │ │ ├── d *** 168 | │ │ ├── c *** 169 | │ │ │ └── d *** 170 | │ │ └── e *** 171 | │ ├── e 172 | │ │ ├── e *** 173 | │ │ ├── d *** 174 | │ │ ├── a *** 175 | │ │ └── y *** 176 | │ ├── a 177 | │ │ └── y *** 178 | │ └── y 179 | │ ├── - 180 | │ │ └── b 181 | │ │ └── y *** 182 | │ └── e *** 183 | │ └── - 184 | │ └── b 185 | │ └── y 186 | │ └── e *** 187 | ├── a 188 | │ └── b 189 | │ └── c *** 190 | └── z 191 | ├── a 192 | │ └── d *** 193 | └── e 194 | ├── d *** 195 | └── f *** 196 | 197 | list of words in trie: 198 | [abc, bay, bea, bed, bee, bey, boy, boyc, boycd, boyd, boye, by-by, bye, bye-bye, zad, zed, zef] 199 | 200 | contains boy? true 201 | contains bo? false 202 | contains boye? true 203 | contains byebye? false 204 | contains bye-bye? true 205 | 206 | contains prefix bo? true 207 | contains prefix b o? false 208 | contains prefix bye? true 209 | contains prefix ye? false 210 | */ 211 | } 212 | } 213 | --------------------------------------------------------------------------------