《算法》第三章部分程序 part 3

▶ 书中第三章部分程序,加上自己补充的代码,红黑树

● 红黑树,大部分方法与注释与二叉树相同

  1 package package01;
  2 
  3 import java.util.NoSuchElementException;
  4 import edu.princeton.cs.algs4.Queue;
  5 import edu.princeton.cs.algs4.StdIn;
  6 import edu.princeton.cs.algs4.StdOut;
  7 
  8 public class class01<Key extends Comparable<Key>, Value>
  9 {
 10     private static final boolean RED = true;
 11     private static final boolean BLACK = false;
 12 
 13     private class Node
 14     {
 15         private Key key;
 16         private Value val;
 17         private Node left, right;
 18         private boolean color;     // 指向该节点的连接的颜色
 19         private int size;
 20 
 21         public Node(Key key, Value val, boolean color, int size)
 22         {
 23             this.key = key;
 24             this.val = val;
 25             this.color = color;
 26             this.size = size;
 27         }
 28     }
 29 
 30     private Node root;
 31 
 32     public class01() {}
 33 
 34     private boolean isRed(Node x)
 35     {
 36         if (x == null)
 37             return false;
 38         return x.color == RED;
 39     }
 40 
 41     public int size()
 42     {
 43         return size(root);
 44     }
 45 
 46     private int size(Node x)
 47     {
 48         if (x == null)
 49             return 0;
 50         return x.size;
 51     }
 52 
 53     public boolean isEmpty()
 54     {
 55         return size() == 0; //return root == null;
 56     }
 57 
 58     public Value get(Key key)               // 查找
 59     {
 60         if (key == null)
 61             throw new IllegalArgumentException("\n<get> key == null.\n");
 62         return getKernel(root, key);
 63     }
 64 
 65     private Value getKernel(Node x, Key key)// 查找内核,使用了非递归实现
 66     {
 67         for (int cmp = key.compareTo(x.key); x != null; cmp = key.compareTo(x.key))
 68         {
 69             if (cmp < 0)
 70                 x = x.left;
 71             else if (cmp > 0)
 72                 x = x.right;
 73             else
 74                 return x.val;
 75         }
 76         return null;
 77     }
 78 
 79     public boolean contains(Key key)        // 判断 key 是否在树中
 80     {
 81         if (key == null)
 82             throw new IllegalArgumentException("\n<contains> key == null.\n");
 83         return get(key) != null;
 84     }
 85 
 86     public void put(Key key, Value val)     // 插入
 87     {
 88         if (key == null)
 89             throw new IllegalArgumentException("\n<put> key == null.\n");
 90         if (val == null)
 91             delete(key);
 92         else
 93         {
 94             root = putKernel(root, key, val);
 95             root.color = BLACK;
 96         }
 97         // assert check();
 98     }
 99 
100     private Node putKernel(Node x, Key key, Value val)
101     {
102         if (x == null)
103             return new Node(key, val, RED, 1);
104         int cmp = key.compareTo(x.key);
105         if (cmp < 0)
106             x.left = putKernel(x.left, key, val);
107         else if (cmp > 0)
108             x.right = putKernel(x.right, key, val);
109         else
110             x.val = val;
111         if (isRed(x.right) && !isRed(x.left))
112             x = rotateLeft(x);
113         if (isRed(x.left) && isRed(x.left.left))
114             x = rotateRight(x);
115         if (isRed(x.left) && isRed(x.right))
116             flipColors(x);
117         x.size = 1 + size(x.left) + size(x.right);
118         return x;
119     }
120 
121     public void deleteMin()
122     {
123         if (isEmpty())
124             throw new NoSuchElementException("\n<deleteMin> underflow.\n");
125         if (!isRed(root.left) && !isRed(root.right))
126             root.color = RED;
127         root = deleteMinKernel(root);
128         if (!isEmpty())
129             root.color = BLACK;
130         // assert check();
131     }
132 
133     private Node deleteMinKernel(Node x)
134     {
135         if (x.left == null)
136             return null;
137         if (!isRed(x.left) && !isRed(x.left.left))
138             x = moveRedLeft(x);
139         x.left = deleteMinKernel(x.left);
140         return balance(x);
141     }
142 
143     public void deleteMax()
144     {
145         if (isEmpty())
146             throw new NoSuchElementException("\n<deleteMax> underflow.\n");
147         if (!isRed(root.left) && !isRed(root.right))
148             root.color = RED;
149         root = deleteMaxKernel(root);
150         if (!isEmpty())
151             root.color = BLACK;
152         // assert check();
153     }
154 
155     private Node deleteMaxKernel(Node x)
156     {
157         if (isRed(x.left))
158             x = rotateRight(x);
159         if (x.right == null)
160             return null;
161         if (!isRed(x.right) && !isRed(x.right.left))
162             x = moveRedRight(x);
163         x.right = deleteMaxKernel(x.right);
164         return balance(x);
165     }
166 
167     public void delete(Key key)
168     {
169         if (key == null)
170             throw new IllegalArgumentException("\n<delete> key == null.\n");
171         if (!contains(key))
172             return;
173         if (!isRed(root.left) && !isRed(root.right))
174             root.color = RED;
175         root = deleteKernel(root, key);
176         if (!isEmpty())
177             root.color = BLACK;
178         // assert check();
179     }
180 
181     private Node deleteKernel(Node x, Key key)
182     {
183         if (key.compareTo(x.key) < 0)
184         {
185             if (!isRed(x.left) && !isRed(x.left.left))
186                 x = moveRedLeft(x);
187             x.left = deleteKernel(x.left, key);
188         }
189         else
190         {
191             if (isRed(x.left))
192                 x = rotateRight(x);
193             if (key.compareTo(x.key) == 0 && (x.right == null))
194                 return null;
195             if (!isRed(x.right) && !isRed(x.right.left))
196                 x = moveRedRight(x);
197             if (key.compareTo(x.key) == 0)
198             {
199                 Node t = minKernel(x.right);
200                 x.key = t.key;
201                 x.val = t.val;
202                 // x.val = get(x.right, min(x.right).key);
203                 // x.key = min(x.right).key;
204                 x.right = deleteMinKernel(x.right);
205             }
206             else x.right = deleteKernel(x.right, key);
207         }
208         return balance(x);
209     }
210 
211     private Node rotateRight(Node x)    // 右旋转
212     {
213         Node t = x.left;
214         x.left = t.right;
215         t.right = x;
216         t.color = t.right.color;
217         t.right.color = RED;
218         t.size = x.size;
219         x.size = 1 + size(x.left) + size(x.right);
220         return t;
221     }
222 
223     private Node rotateLeft(Node x)     // 左旋转
224     {
225         Node t = x.right;
226         x.right = t.left;
227         t.left = x;
228         t.color = t.left.color;
229         t.left.color = RED;
230         t.size = x.size;
231         x.size = 1 + size(x.left) + size(x.right);
232         return t;
233     }
234 
235     private void flipColors(Node x)     // 改变节点及其子节点的颜色
236     {
237         // assert (x != null) && (x.left != null) && (x.right != null);
238         // assert (!isRed(x) &&  isRed(x.left) &&  isRed(x.right)) || (isRed(x)  && !isRed(x.left) && !isRed(x.right));
239         x.color = !x.color;
240         x.left.color = !x.left.color;
241         x.right.color = !x.right.color;
242     }
243 
244     private Node moveRedLeft(Node x)    // x 红而 x.left 和 x.left.left 都是黑的,调整使得两个黑链接之一变红
245     {
246         // assert (x != null);
247         // assert isRed(x) && !isRed(x.left) && !isRed(x.left.left);
248         flipColors(x);
249         if (isRed(x.right.left))
250         {
251             x.right = rotateRight(x.right);
252             x = rotateLeft(x);
253             flipColors(x);
254         }
255         return x;
256     }
257 
258     private Node moveRedRight(Node x)    // x 红而 x.right 和 x.right.left 都是黑的,调整使得两黑链接之一变红
259     {
260         // assert (x != null);
261         // assert isRed(x) && !isRed(x.right) && !isRed(x.right.left);
262         flipColors(x);
263         if (isRed(x.left.left))
264         {
265             x = rotateRight(x);
266             flipColors(x);
267         }
268         return x;
269     }
270 
271     private Node balance(Node x)        // 右链接红色、连续两层左链接红色以及左右链接都是红色的状况,分别调整
272     {
273         // assert (x != null);
274         if (isRed(x.right))
275             x = rotateLeft(x);
276         if (isRed(x.left) && isRed(x.left.left))
277             x = rotateRight(x);
278         if (isRed(x.left) && isRed(x.right))
279             flipColors(x);
280         x.size = 1 + size(x.left) + size(x.right);
281         return x;
282     }
283 
284     public Key min()
285     {
286         if (isEmpty())
287             throw new NoSuchElementException("\n<delete> empty.\n");
288         return minKernel(root).key;
289     }
290 
291     private Node minKernel(Node x)
292     {
293         if (x.left == null)
294             return x;
295         return minKernel(x.left);
296     }
297 
298     public Key max()
299     {
300         if (isEmpty())
301             throw new NoSuchElementException("\n<max> empty.\n");
302         return maxKernel(root).key;
303     }
304 
305     private Node maxKernel(Node x)
306     {
307         if (x.right == null)
308             return x;
309         return maxKernel(x.right);
310     }
311 
312     public Key floor(Key key)
313     {
314         if (key == null)
315             throw new IllegalArgumentException("\n<floor> key == null.\n");
316         if (isEmpty())
317             throw new NoSuchElementException("\n<floor> empty.\n");
318         Node x = floorKernel(root, key);
319         return (x == null) ? null : x.key;
320     }
321 
322     private Node floorKernel(Node x, Key key)
323     {
324         if (x == null)
325             return null;
326         int cmp = key.compareTo(x.key);
327         if (cmp == 0)
328             return x;
329         if (cmp < 0)
330             return floorKernel(x.left, key);
331         Node t = floorKernel(x.right, key);
332         return (t == null) ? x : t;
333     }
334 
335     public Key ceiling(Key key)
336     {
337         if (key == null)
338             throw new IllegalArgumentException("\n<ceiling> key == null.\n");
339         if (isEmpty())
340             throw new NoSuchElementException("\n<ceiling> empty.\n");
341         Node x = ceilingKernel(root, key);
342         return (x == null) ? null : x.key;
343     }
344 
345     private Node ceilingKernel(Node x, Key key)
346     {
347         if (x == null)
348             return null;
349         int cmp = key.compareTo(x.key);
350         if (cmp == 0)
351             return x;
352         if (cmp > 0)
353             return ceilingKernel(x.right, key);
354         Node t = ceilingKernel(x.left, key);
355         return (t == null) ? x : t;
356     }
357 
358     public Key select(int k)
359     {
360         if (k < 0 || k >= size())
361             throw new IllegalArgumentException("\n<select> k < 0 || k >= size().\n");
362         return selectKernel(root, k).key;
363     }
364 
365     private Node selectKernel(Node x, int k)
366     {
367         if (x == null)
368             return null;
369         int t = size(x.left);
370         if (k <t)
371             return selectKernel(x.left, k);
372         if (k > t)
373             return selectKernel(x.right, k - t - 1);
374         return x;
375     }
376 
377     public int rank(Key key)
378     {
379         if (key == null)
380             throw new IllegalArgumentException("\n<rank> key == null.\n");
381         return rankKernel(key, root);
382     }
383 
384     private int rankKernel(Key key, Node x)
385     {
386         if (x == null)
387             return 0;
388         int cmp = key.compareTo(x.key);
389         if (cmp < 0)
390             return rankKernel(key, x.left);
391         if (cmp > 0)
392             return 1 + size(x.left) + rankKernel(key, x.right);
393         return size(x.left);
394     }
395 
396     public Iterable<Key> keys()
397     {
398         if (isEmpty())
399             return new Queue<Key>();
400         Key lo = min(), hi = max();
401         if (lo == null)
402             throw new IllegalArgumentException("\n<iterable> lo == null.\n");
403         if (hi == null)
404             throw new IllegalArgumentException("\n<iterable> hi == null.\n");
405         Queue<Key> queue = new Queue<Key>();
406         // if (isEmpty() || lo.compareTo(hi) > 0) return queue;
407         keysKernel(root, queue, lo, hi);
408         return queue;
409     }
410 
411     private void keysKernel(Node x, Queue<Key> queue, Key lo, Key hi)
412     {
413         if (x == null)
414             return;
415         int cmplo = lo.compareTo(x.key), cmphi = hi.compareTo(x.key);
416         if (cmplo < 0)
417             keysKernel(x.left, queue, lo, hi);
418         if (cmplo <= 0 && cmphi >= 0)
419             queue.enqueue(x.key);
420         if (cmphi > 0)
421             keysKernel(x.right, queue, lo, hi);
422     }
423 
424     public Iterable<Key> levelOrder()
425     {
426         Queue<Key> keys = new Queue<Key>();
427         Queue<Node> queue = new Queue<Node>();
428         for (queue.enqueue(root); !queue.isEmpty();)
429         {
430             Node x = queue.dequeue();
431             if (x == null)
432                 continue;
433             keys.enqueue(x.key);
434             queue.enqueue(x.left);
435             queue.enqueue(x.right);
436         }
437         return keys;
438     }
439 
440     public int size(Key lo, Key hi)
441     {
442         if (lo == null)
443             throw new IllegalArgumentException("\n<size> lo == null.\n");
444         if (hi == null)
445             throw new IllegalArgumentException("\n<size> hi == null.\n");
446         if (lo.compareTo(hi) > 0)
447             return 0;
448         if (contains(hi))
449             return rank(hi) - rank(lo) + 1;
450         return rank(hi) - rank(lo);
451     }
452 
453     public int height()
454     {
455         return heightKernel(root);
456     }
457 
458     private int heightKernel(Node x)
459     {
460         if (x == null)
461             return -1;
462         return 1 + Math.max(heightKernel(x.left), heightKernel(x.right));
463     }    
464 
465     private boolean check()
466     {
467         if (!isBST())
468             StdOut.println("\n<check> Not in symmetric order.\n");
469         if (!isSizeConsistent())
470             StdOut.println("\n<check> Subtree counts not consistent.\n");
471         if (!isRankConsistent())
472             StdOut.println("\n<check> Ranks not consistent.\n");
473         if (!is23())
474             StdOut.println("\n<check> Not a 2 - 3 tree.\n");
475         if (!isBalanced())
476             StdOut.println("\n<check> Not balanced.\n");
477         return isBST() && isSizeConsistent() && isRankConsistent() && is23() && isBalanced();
478     }
479 
480     private boolean isBST()
481     {
482         return isBSTKernel(root, null, null);
483     }
484 
485     private boolean isBSTKernel(Node x, Key min, Key max)
486     {
487         if (x == null)
488             return true;
489         if (min != null && x.key.compareTo(min) <= 0)
490             return false;
491         if (max != null && x.key.compareTo(max) >= 0)
492             return false;
493         return isBSTKernel(x.left, min, x.key) && isBSTKernel(x.right, x.key, max);
494     }
495     
496     private boolean isSizeConsistent()
497     {
498         return isSizeConsistentKernel(root);
499     }
500 
501     private boolean isSizeConsistentKernel(Node x)
502     {
503         if (x == null)
504             return true;
505         if (x.size != 1 + size(x.left) + size(x.right))
506             return false;
507         return isSizeConsistentKernel(x.left) && isSizeConsistentKernel(x.right);
508     }
509 
510     private boolean isRankConsistent()
511     {
512         for (int i = 0; i < size(); i++)
513         {
514             if (i != rank(select(i)))
515                 return false;
516         }
517         for (Key key : keys())
518         {
519             if (key.compareTo(select(rank(key))) != 0)
520                 return false;
521         }
522         return true;
523     }
524 
525     private boolean is23()
526     {
527         return is23Kernel(root);
528     }
529 
530     private boolean is23Kernel(Node x)
531     {
532         if (x == null)
533             return true;
534         if (isRed(x.right))
535             return false;
536         if (x != root && isRed(x) && isRed(x.left))
537             return false;
538         return is23Kernel(x.left) && is23Kernel(x.right);
539     }
540 
541     private boolean isBalanced()
542     {
543         int black = 0;                          // 从 root 到 min 节点的路径长        
544         for(Node x = root;x != null; x = x.left)
545         {
546             if (!isRed(x)) 
547                 black++;            
548         }
549         return isBalancedKernel(root, black);
550     }
551 
552     private boolean isBalancedKernel(Node x, int black)
553     {
554         if (x == null) 
555             return black == 0;
556         if (!isRed(x)) 
557             black--;
558         return isBalancedKernel(x.left, black) && isBalancedKernel(x.right, black);
559     }
560 
561     public static void main(String[] args)
562     {
563         class01<String, Integer> st = new class01<String, Integer>();
564         for (int i = 0; !StdIn.isEmpty(); i++)
565         {
566             String key = StdIn.readString();
567             st.put(key, i);
568         }
569 
570         for (String s : st.levelOrder())
571             StdOut.println(s + " " + st.get(s));
572 
573         StdOut.println();
574         for (String s : st.keys())
575             StdOut.println(s + " " + st.get(s));
576     }
577 }// 703

猜你喜欢

转载自www.cnblogs.com/cuancuancuanhao/p/9784763.html