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


    ▶ 书中第三章部分程序,加上自己补充的代码,包括散列表、线性探查表

    ● 散列表

      1 package package01;
      2 
      3 import edu.princeton.cs.algs4.Queue;
      4 import edu.princeton.cs.algs4.SequentialSearchST;
      5 import edu.princeton.cs.algs4.StdIn;
      6 import edu.princeton.cs.algs4.StdOut;
      7 
      8 public class class01<Key, Value>
      9 {
     10     private static final int INIT_CAPACITY = 4;   // 默认构造函数参数
     11     private int n;                                // 待插入元素数
     12     private int m;                                // 散列表尺寸
     13     private SequentialSearchST<Key, Value>[] st;  // 散列表
     14 
     15     public class01()
     16     {
     17         this(INIT_CAPACITY);
     18     }
     19 
     20     public class01(int capacity)
     21     {
     22         m = capacity;
     23         st = (SequentialSearchST<Key, Value>[]) new SequentialSearchST[m];
     24         for (int i = 0; i < m; i++)
     25             st[i] = new SequentialSearchST<Key, Value>();
     26     }
     27 
     28     public int size()
     29     {
     30         return n;
     31     }
     32 
     33     public boolean isEmpty()
     34     {
     35         return size() == 0;
     36     }
     37 
     38     private void resize(int capacity)
     39     {
     40         class01<Key, Value> temp = new class01<Key, Value>(capacity);
     41         for (int i = 0; i < m; i++)
     42         {
     43             for (Key key : st[i].keys())
     44                 temp.put(key, st[i].get(key));
     45         }
     46         m = temp.m;
     47         n = temp.n;
     48         st = temp.st;
     49     }
     50 
     51     public boolean contains(Key key)
     52     {
     53         if (key == null)
     54             throw new IllegalArgumentException("
    <contains> key == null.
    ");
     55         return get(key) != null;
     56     }
     57 
     58     private int hash(Key key)
     59     {
     60         return (key.hashCode() & 0x7fffffff) % m;
     61     }
     62 
     63     public Value get(Key key)
     64     {
     65         if (key == null)
     66             throw new IllegalArgumentException("
    <get> key == null.
    ");
     67         return st[hash(key)].get(key);
     68     }
     69 
     70     public void put(Key key, Value val)
     71     {
     72         if (key == null)
     73             throw new IllegalArgumentException("
    <get> key == null.
    ");
     74         if (val == null)
     75         {
     76             delete(key);
     77             return;
     78         }
     79         if (n >= 10 * m)                        // 平均链表长度不小于 10,扩容
     80             resize(2 * m);
     81         int i = hash(key);
     82         if (!st[i].contains(key))
     83             n++;
     84         st[i].put(key, val);
     85     }
     86 
     87     public void delete(Key key)
     88     {
     89         if (key == null)
     90             throw new IllegalArgumentException("
    <delete> key == null.
    ");
     91         if (!contains(key))
     92             return;
     93         int i = hash(key);
     94         if (st[i].contains(key))
     95             n--;
     96         st[i].delete(key);
     97         if (m > INIT_CAPACITY && n <= 2 * m)    // 平均链表长度小于 2,缩容
     98             resize(m / 2);
     99     }
    100 
    101     public Iterable<Key> keys()
    102     {
    103         Queue<Key> queue = new Queue<Key>();
    104         for (int i = 0; i < m; i++)
    105         {
    106             for (Key key : st[i].keys())
    107                 queue.enqueue(key);
    108         }
    109         return queue;
    110     }
    111 
    112     public static void main(String[] args)
    113     {
    114         class01<String, Integer> st = new class01<String, Integer>();
    115         for (int i = 0; !StdIn.isEmpty(); i++)
    116         {
    117             String key = StdIn.readString();
    118             st.put(key, i);
    119         }
    120         for (String s : st.keys())
    121             StdOut.println(s + " " + st.get(s));
    122     }
    123 }

    ● 线性探查表

      1 package package01;
      2 
      3 import edu.princeton.cs.algs4.Queue;
      4 import edu.princeton.cs.algs4.StdIn;
      5 import edu.princeton.cs.algs4.StdOut;
      6 
      7 public class class01<Key, Value>
      8 {
      9     private static final int INIT_CAPACITY = 4;
     10     private int n;
     11     private int m;
     12     private Key[] keys;
     13     private Value[] vals;
     14 
     15     public class01()
     16     {
     17         this(INIT_CAPACITY);
     18     }
     19 
     20     public class01(int capacity)
     21     {
     22         m = capacity;
     23         n = 0;
     24         keys = (Key[])   new Object[m];
     25         vals = (Value[]) new Object[m];
     26     }
     27 
     28     public int size()
     29     {
     30         return n;
     31     }
     32 
     33     public boolean isEmpty()
     34     {
     35         return size() == 0;
     36     }
     37 
     38     private void resize(int capacity)
     39     {
     40         class01<Key, Value> temp = new class01<Key, Value>(capacity);
     41         for (int i = 0; i < m; i++)
     42         {
     43             if (keys[i] != null)
     44                 temp.put(keys[i], vals[i]);
     45         }
     46         m = temp.m;
     47         keys = temp.keys;
     48         vals = temp.vals;
     49 
     50     }
     51 
     52     public boolean contains(Key key)
     53     {
     54         if (key == null)
     55             throw new IllegalArgumentException("
    <contains> key == null.
    ");
     56         return get(key) != null;
     57     }
     58 
     59     private int hash(Key key)
     60     {
     61         return (key.hashCode() & 0x7fffffff) % m;
     62     }
     63 
     64     public Value get(Key key)
     65     {
     66         if (key == null)
     67             throw new IllegalArgumentException("
    <get> key == null.
    ");
     68         for (int i = hash(key); keys[i] != null; i = (i + 1) % m)   // 表荷载不会超过 1/2,所以不会绕圈
     69         {
     70             if (keys[i].equals(key))
     71                 return vals[i];
     72         }
     73         return null;
     74     }
     75 
     76     public void put(Key key, Value val)
     77     {
     78         if (key == null)
     79             throw new IllegalArgumentException("
    <get> key == null.
    ");
     80         if (val == null)
     81         {
     82             delete(key);
     83             return;
     84         }
     85         if (n >= m / 2)                                             // 荷载超过一半了,扩容
     86             resize(2 * m);
     87         int i;
     88         for (i = hash(key); keys[i] != null; i = (i + 1) % m)
     89         {
     90             if (keys[i].equals(key))
     91             {
     92                 vals[i] = val;
     93                 return;
     94             }
     95         }
     96         keys[i] = key;
     97         vals[i] = val;
     98         n++;
     99     }
    100 
    101     public void delete(Key key)
    102     {
    103         if (key == null)
    104             throw new IllegalArgumentException("
    <delete> key == null.
    ");
    105         if (!contains(key))
    106             return;
    107         int i = hash(key);
    108         for (; !key.equals(keys[i]); i = (i + 1) % m);              // 找到目标元素
    109         keys[i] = null;                                             // 删除目标元素
    110         vals[i] = null;
    111         for (i = (i + 1) % m; keys[i] != null; i = (i + 1) % m)     // 在下一个 null 之前,所有元素重新插入
    112         {
    113             Key   keyToRehash = keys[i];
    114             Value valToRehash = vals[i];
    115             keys[i] = null;
    116             vals[i] = null;
    117             n--;
    118             put(keyToRehash, valToRehash);
    119         }
    120         n--;
    121         if (n > 0 && n <= m / 8)                                    // 荷载小于 1/8, 缩容
    122             resize(m / 2);
    123     }
    124 
    125     public Iterable<Key> keys()
    126     {
    127         Queue<Key> queue = new Queue<Key>();
    128         for (int i = 0; i < m; i++)
    129         {
    130             if (keys[i] != null)
    131                 queue.enqueue(keys[i]);
    132         }
    133         return queue;
    134     }
    135     private boolean check()
    136     {
    137         if (m < 2 * n)                                      // 检查容量
    138         {
    139             System.err.println("
    <check> m < 2 * n.
    ");
    140             return false;
    141         }
    142         for (int i = 0; i < m; i++)                         // 检查 hash
    143         {
    144             if (keys[i] == null)
    145                 continue;
    146             if (get(keys[i]) != vals[i])
    147             {
    148                 System.err.println("
    <check> hash error at i = ", i, ", key[i] = ", get(keys[i]), ", val[i] = ", vals[i], ".
    ");
    149                 return false;
    150             }
    151         }
    152         return true;
    153     }
    154 
    155     public static void main(String[] args)
    156     {
    157         class01<String, Integer> st = new class01<String, Integer>();
    158         for (int i = 0; !StdIn.isEmpty(); i++)
    159         {
    160             String key = StdIn.readString();
    161             st.put(key, i);
    162         }
    163         for (String s : st.keys())
    164             StdOut.println(s + " " + st.get(s));
    165     }
    166 }
  • 相关阅读:
    浏览器中包含什么?三个常驻线程?
    TCP粘包和拆包
    TCP有限状态机
    TCP的拥塞控制
    TCP滑动窗口实现流量控制
    http状态码及意义
    OSI七层结构
    浏览器的event loop
    history api
    表单提交的方式
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9795423.html
Copyright © 2020-2023  润新知