标签:style http color java 使用 io strong for ar
search by hashing
解决顺序查找一一对比的问题,对存入数据的key取hashcode并存入array,查找数据时以key的hashcode作为索引返回数据。
hash collision
没有一种hash算法可以避免hash冲突,所以在发生冲突时要解决冲突:
1,Open Addressiong
当发生冲突时,把冲突的值存入下一个open的位置。
1.1, linear probing
设index=hash(key),发生冲突时尝试存入index + 1,如果仍然冲突存入index+2,一次类推知道找到n使得index + n的位置open,如果index + n > size,则从1重新查找。
1.2, double hashing
思路同1.1,不同在于查找open位置是使用hash2算法——index = (index +hash2(key) )% size,如果仍然冲突则继续index = (index +hash2(key) )% size,直到找到open的位置。
一个问题是double hashing可能不会遍历所有的index就回到了开始位置,解决这个问题要保证hash2与size之间是相对素数(不存在公因子)。
1. hash2(key) = 1 + (key % (SIZE - 2) 2. hash2(key) = max(1, (key / SIZE) % SIZE)
2, Chained hashing
hash表的location位置上存的不再是数据,而是一个linkedList,在发生冲突时把新的数据添加到链表中。
算法效率
1,最坏效率与线性查找一直,即所有的entry的hashcode一样,算法退化为线性查找。
2,平均情况下,需要引入load factor概念——loadfactor=recordCount/size,其中recordCount是当前保持数据的数量,size是hash表的容量。Open Addressing方案中load factor小于等于1,Chained hashing中load factor可以高于1。
Load factor (alpha) | Open addressing with linear probing (1+1/(1-alpha))/2 |
Open addressing with double hashing -ln(1-alpha)/alpha |
Chained hashing 1+alpha/2 |
0.5 | 1.50 | 1.39 | 1.25 |
0.6 | 1.75 | 1.53 | 1.30 |
0.7 | 2.17 | 1.72 | 1.35 |
0.8 | 3.00 | 2.01 | 1.40 |
0.9 | 5.50 | 2.56 | 1.45 |
1.0 | N/A | N/A | 1.50 |
2.0 | N/A | N/A | 2.00 |
4.0 | N/A | N/A | 3.00 |
Java中的hashmap
hashmap使用chained hashing的方式实现,并且根据load factor的大小动态调整hash表的capacity。
put 方法:
public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
2,根据hashcode确定在表中的index。
3,遍历index的值,如果找到key相同的Entry则做更新操作,否则知道添加当前值到链表中。
addEntry方法:
void addEntry(int hash, K key, V value, int bucketIndex) { if ((size >= threshold) && (null != table[bucketIndex])) { resize(2 * table.length); hash = (null != key) ? hash(key) : 0; bucketIndex = indexFor(hash, table.length); } createEntry(hash, key, value, bucketIndex); }
2,添加当前值。
threshold的计算:
threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
https://www.cs.bu.edu/teaching/cs113/spring-2000/hash/
标签:style http color java 使用 io strong for ar
原文地址:http://my.oschina.net/pangyangyang/blog/306539