《算法》第三章部分程序 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 }
原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9795423.html