码迷,mamicode.com
首页 > 其他好文 > 详细

词典的实现(4)-使用Hash方式来实现词典

时间:2015-07-02 22:25:20      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

1,实现思路

public class HashedDictionary<K, V> implements DictionaryInterface<K, V>,
        Serializable {

定义HashedDictionary.java,作为Hash词典的实现,该词典实现了如下功能:

①向词典中添加元素 ,②根据查找键从词典中删除元素, ③从词典中获取某个查找键的值, ④实现了词典中查找键Key的迭代器和Value的迭代器

 

2,对于Map词典而言,由第一行代码知:它底层实质上是一个数组。

第三行代码中的locationUsed 用来记录哈希表中某个位置是否被使用。由于冲突处理的需要,当删除某个元素时,只是将该元素作为标记删除而不是真正删除该元素,那么该元素所占用的位置实质上是已经被使用了的。但是,关于这个变量,程序还是有问题的。

1     private TableEntry<K, V>[] hashTable;
2     private int numberOfEntries;//hashTable元素个数
3     private int locationUsed;//记录hashTable 位置的使用
4     private static final int DEFAULT_SIZE = 101;// 哈希表的默认大小,素数
5     private static final double MAX_LOAD_FACTOR = 0.5;// 装载因子

 

3,构造函数,用来生成一个Hash词典实例,从第六行代码看出,它实质上是 new 一个TableEntry类型的数组,而这个数组就是用来存放<key,value>对的索引。TableEntry是HashedDictionary的一个内部类,正是由它来封装实际的<key,value>元素,而HashedDictionary的对象就代表一个词典,词典的基本操作就是操作TableEntry数组指向的每个<key,value>

1     public HashedDictionary(int tableSize) {
2         /*
3          * 当用来构造哈希表的参数不是素数时,寻找与该参数最接近的下一个素数
4          */
5         int primeSize = getNextPrime(tableSize);
6         hashTable = new TableEntry[primeSize];
7         numberOfEntries = 0;
8         locationUsed = 0;
9     }
1 private class TableEntry<S, T> implements Serializable {
2         private S entryKey;
3         private T entryValue;
4         private boolean inTable;

 

4,再看看迭代器的实现

这两个内部分别用来实现Key的迭代器和Value的迭代器,只需要实现在Iterator接口中定义好的方法即可,然后在HashedDictionary.java中再定义两个函数用来获得KeyIterator类型和ValueIterator类型的迭代器即可。

private class KeyIterator implements Iterator<K>{
......

private class ValueIterator implements Iterator<V>{
public Iterator<K> getKeyIterator() {
        return new KeyIterator();
    }
public Iterator<V> getValueIterator() { return new ValueIterator(); }

 

5,哈希函数是如何实现的

1     private int getHashIndex(K key){
2         //先获得散列码,再通过 % 将散列码压缩为索引
3         int hashIndex = key.hashCode() % hashTable.length;
4         if(hashIndex < 0)
5             hashIndex = hashIndex + hashTable.length;
6         return hashIndex;
7     }

 

 

6,在添加<key,value>元素时是如何处理冲突的?这里采用了开放定址之线性探测法处理冲突。

调用probe(index,key)来处理冲突

 

 

1     public V add(K key, V value) {
2         V oldValue;
3         if(isFull())
4             rehash();
5         int index = getHashIndex(key);
6         index = probe(index, key);//线性探测
 1 private int probe(int index, K key){
 2         boolean found = false;
 3         int removedStateIndex = -1;
 4         while(!found && (hashTable[index] != null)){
 5             if(hashTable[index].isIn()){
 6                 if(key.equals(hashTable[index].getEntryKey()))
 7                     found = true;
 8                 else
 9                     index = (index + 1) % hashTable.length;
10             }
11             else
12             {//保存处于已删除状态的第一个位置的索引
13                 if(removedStateIndex == -1)
14                     removedStateIndex = index;
15                 index = (index + 1) % hashTable.length;//线性探测
16             }
17         }//end while
18         if(found || (removedStateIndex == -1))
19             return index;
20         else
21             return removedStateIndex;
22     }

 

 

7,由于可能产生冲突,某个Key通过散列函数生成索引之后,该索引位置可能已经存放了其它元素,那它又是如何正确地通过getValue(K key)方法来正确取得key所对应的value?-----locate(index, key)函数的功能。

 

 

 

1     public V getValue(K key) {
2         V result = null;
3         int index = getHashIndex(key);//获得key对应的哈希索引
4         index = locate(index, key);//返回处理冲突后的最终的索引地址
5         
6         if(index != -1)
7             result = hashTable[index].getEntryValue();
8         return result;
9     }
 1 private int locate(int index, K key){
 2         boolean found = false;
 3         //当找到一个hashTable中为null的元素,表示查找失败
 4         while(!found && (hashTable[index] != null)){
 5             //index 处 的key对应的value没有被标记删除且key 相同时
 6             if(hashTable[index].isIn() && key.equals(hashTable[index].getEntryKey()))
 7                 found = true;
 8             else 
 9                 index = (index + 1) % hashTable.length;
10         }
11         int result = -1;
12         if(found)
13             result = index;
14         return result;
15     }

 

第5---7还需要进一步解释。未完。。最终会把完整的代码提交到github上。

 

词典的实现(4)-使用Hash方式来实现词典

标签:

原文地址:http://www.cnblogs.com/hapjin/p/4611624.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!