zoukankan      html  css  js  c++  java
  • 《算法》第三章部分程序 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("
    <get> key == null.
    ");
     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("
    <contains> key == null.
    ");
     83         return get(key) != null;
     84     }
     85 
     86     public void put(Key key, Value val)     // 插入
     87     {
     88         if (key == null)
     89             throw new IllegalArgumentException("
    <put> key == null.
    ");
     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("
    <deleteMin> underflow.
    ");
    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("
    <deleteMax> underflow.
    ");
    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("
    <delete> key == null.
    ");
    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("
    <delete> empty.
    ");
    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("
    <max> empty.
    ");
    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("
    <floor> key == null.
    ");
    316         if (isEmpty())
    317             throw new NoSuchElementException("
    <floor> empty.
    ");
    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("
    <ceiling> key == null.
    ");
    339         if (isEmpty())
    340             throw new NoSuchElementException("
    <ceiling> empty.
    ");
    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("
    <select> k < 0 || k >= size().
    ");
    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("
    <rank> key == null.
    ");
    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("
    <iterable> lo == null.
    ");
    403         if (hi == null)
    404             throw new IllegalArgumentException("
    <iterable> hi == null.
    ");
    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("
    <size> lo == null.
    ");
    444         if (hi == null)
    445             throw new IllegalArgumentException("
    <size> hi == null.
    ");
    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("
    <check> Not in symmetric order.
    ");
    469         if (!isSizeConsistent())
    470             StdOut.println("
    <check> Subtree counts not consistent.
    ");
    471         if (!isRankConsistent())
    472             StdOut.println("
    <check> Ranks not consistent.
    ");
    473         if (!is23())
    474             StdOut.println("
    <check> Not a 2 - 3 tree.
    ");
    475         if (!isBalanced())
    476             StdOut.println("
    <check> Not balanced.
    ");
    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
  • 相关阅读:
    Linux终端复用——tmux
    python中的global和nonlocal
    Pytorch中的错误和bug
    vue之Mutations 理解
    js 对象的合并(3种方法)转载
    json 数组
    vue-cli 安装时 npm 报错 errno -4048
    vue-cli 安装步骤(转载)
    安卓输入框调起键盘后输入框自动上浮
    jquery on 事件嵌套 事件执行多次
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9784763.html
Copyright © 2011-2022 走看看