哈希表

哈希表的几个特殊应用实现:

 

1.* 设计一个数据结构,使得该结构再插入,删除和随机获取结构中的数据的时间复杂度均为O(1)

 1 public class RandomPools {
 2     public static class Pool<K> {
 3         HashMap<K,Integer> keyIndexMap;
 4         HashMap<Integer,K> indexKeyMap;
 5         int size;
 6         
 7         public Pool() {
 8             keyIndexMap = new HashMap<>();
 9             indexKeyMap = new HashMap<>();
10             size = 0;
11         }
12         
13         public void insert(K key) {
14             if (!keyIndexMap.containsKey(key)) {
15                 keyIndexMap.put(key, size);
16                 indexKeyMap.put(size++, key);
17             }
18         }
19         
20         public void delete(K key) {//将要删的那个值移到最后再删除
21             if (keyIndexMap.containsKey(key)) {
22                 int deleteIndex = keyIndexMap.get(key);
23                 int lastIndex = --size;
24                 K lastKey = indexKeyMap.get(lastIndex);
25                 keyIndexMap.put(lastKey, deleteIndex);
26                 indexKeyMap.put(deleteIndex, lastKey);
27                 keyIndexMap.remove(key);
28                 indexKeyMap.remove(lastIndex);
29             }
30         }
31         
32         public K getRandom() {
33             if (this.size == 0) {
34                 return null;
35             }
36             int randomIndex = (int)(Math.random() * this.size); 
37             return indexKeyMap.get(randomIndex);
38         }
39     }
40 }

 

2. 位图:对于只要用两种状态就可以表示的信息,可以用一位来表示(即无需用int,long等类型,造成不必要空间浪费)

 1 public static void main(String[] args) {
 2         int[] nums = new int[10];//10 * 32bit -> 320bit
 3         
 4         int i = 178;//获取第178bit上的位值(为0还是1)
 5         
 6         int numIndex = i / 32;//确定该位在哪个int类型的数当中
 7         int bitIndex = i % 32;//确定在int类型数中的哪个位置
 8         
 9         //获取该位的信息
10         int s = (nums[numIndex] >> bitIndex) & 1;
11         
12         System.out.println(s);
13         
14         //将该位的信息置1
15         nums[numIndex] = nums[numIndex] | (1 << bitIndex);
16         
17         //将该位的信息置0
18         nums[numIndex] = nums[numIndex] & (~(1 << bitIndex));
19     }

 

3.布隆过滤器:
   

用于判断该值是否处在所要过滤的范围内
* 构建一个长度为m的位图,将所有要过滤的数据进行遍历记录:
* 建立过滤范围:将每个数据通过多个Hash函数得到多个哈希值,并%m,将得到的所有值在位图上做一个标记。
* 遍历完所有的数据并依次进行标记。
* 标记完位图后,即可用该位图判断其他数据是否是在过滤的范围内:用同样的多个哈希函数得到多个哈希值,如果这些
* 哈希值全部被标记过,则认为该数据为要过滤的数据,否则则认为不是要过滤的数据
*
* 特点:
* 1.一定不会把要过滤的数据认为成不要过滤的,但可能会把不要过滤的数据认为成要过滤的。
* 2.发生差错的可能与位图的长度m和Hash函数的个数k有关
* m越大发生差错的可能性越低,但可能性的减小速率随着m的增大逐渐降低
* k存在一个中间极值点,使得在该点差错可能性恰好达到最低

posted @ 2022-04-29 09:53  jue1e0  阅读(42)  评论(0)    收藏  举报