`
shenyu
  • 浏览: 122594 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

HashTable 基于开放地址法(二)

 
阅读更多

与前一个HashTable 基本相同(方法说明请参照它),只是当发生Hash冲突时,采用再用哈希法探测步长。

前面当发生Hash冲突时,直接看当前位置下一个有没有空位,这相当于步长为一,但这容易产生聚集,大的聚集产成后Hash的效率会下降,采用Hash法采用的是使用不同的Hash函数来产生一个新的步长。

新的hash有以下要求

非0

与第一个Hash函数不同

除此之外:

这个HashTable的size要求是质数,因此是靠程序自己计算出来的。

基于链表的HashTable请参见HashTable

public class Item {
    private int key;
    private Object value;

    public Item(int key, Object value) {
        this.key = key;
        this.value = value;
    }

    public int key() { return key; }
    public Object value() { return value; }
}

public class HashTable  {
    private Item noItem = new Item(-1,null);       
    private Item[] array;
    private int size;
    public HashTable(int size) {
        assert size > 5;
        array = new Item[findPrimeMoreThan(size * 2 + 1)];
    }

    private int findPrimeMoreThan(int size) {
        while(true) {
            if(isPrime(size)) return size;
            size ++;
        }
    }

    private boolean isPrime(int value) {
        for(int i=2; i<value/2; i++) {
            if(value%i == 0) return false;
        }
        return true;
    }

    private int getStep(int key) {
        return 5 - (key%5);
    }

    public void add(Item item) {
        assert size < array.length ;
        int keyHash = getKeyHash(item.key());
        while(array[keyHash] != null && array[keyHash].key() == -1) {
            keyHash += getStep(item.key());
            keyHash %= array.length;
        }
        array[keyHash] = item;
        size++;
    }

    private int getKeyHash(int value) {
        return value%array.length;
    }

    public Item find(int key) {
        int keyHash = getKeyHash(key);
        while(array[keyHash] != null) {
            if(array[keyHash].key() == key) return array[keyHash];
            keyHash += getStep(key);
            keyHash %= array.length;
        }
        return null;
    }

    public Item remove(int key) {
        int keyHash = getKeyHash(key);
        while(array[keyHash] != null) {
            if(array[keyHash].key() == key) {
                Item result = array[keyHash];
                array[keyHash] = noItem;
                return result;
            }
            keyHash += getStep(key);
            keyHash %= array.length;
        }
        return null;
    }

    public static void main(String[] args) {
        HashTable t = new HashTable(10);
        t.add(new Item(1,"hello"));
        t.add(new Item(6,"world"));
        t.add(new Item(3,"jason"));
        t.add(new Item(104,"orange"));
        t.add(new Item(9,"peter"));

        assert t.find(6).value().equals("world");
        assert t.find(104).value().equals("orange");
        assert t.find(9).value().equals("peter");
        assert t.find(87) == null;
        assert t.remove(3).value().equals("jason");
        assert t.find(3) ==  null;
        assert t.remove(6).value().equals("world");
        assert t.find(6) ==  null;
       
        t.add(new Item(6,"temp"));
        assert t.find(6).value().equals("temp");
    }
}

 

分享到:
评论

相关推荐

    HashTable

    2. 冲突解决:冲突是不可避免的,常见的解决冲突的方法有开放寻址法和链地址法。开放寻址法是在发生冲突时寻找下一个空槽位,而链地址法则是用链表连接所有映射到同一索引的元素。 二、C语言实现的HashTable 1. ...

    HashTable的java实现

    开放地址寻址有多种策略,如线性探测(Linear Probing)、二次探测(Quadratic Probing)和双重散列(Double Hashing)。双重散列是其中的一种,它使用两个不同的哈希函数,当第一次哈希冲突时,使用第二个哈希函数...

    哈希表hashtable实现

    常见的解决冲突的方法有开放寻址法和链地址法。在“hashtable.c”和“hashtable.h”中,很可能采用了链地址法,即每个数组元素实际上是一个链表的头节点,相同哈希值的元素会被链接在一起。 3. 插入操作:当向哈希...

    c#重写HashTable

    `HashTable`是一个基于开放寻址法的散列表实现,它存储键值对,并通过键来查找值。它的主要操作包括添加、删除、查找元素。由于`HashTable`是非泛型的,这意味着它不支持编译时类型检查,可能导致运行时类型转换...

    实例5 哈希表(Hashtable)和枚举器

    如果多个键的哈希值相同,就会发生哈希冲突,这时哈希表通常采用链地址法或者开放寻址法来解决冲突。 在Java的`Hashtable`中,每个键值对都是通过`Entry`对象来表示的,这些`Entry`对象构成了内部的哈希表。插入...

    基于C语言的数据结构-哈希表hashTable

    常见的方法有开放寻址法(线性探测、二次探测、双哈希探测等)和链地址法(每个槽位存储一个链表)。 二、C语言实现哈希表 1. 定义数据结构:首先,我们需要定义哈希表的结构体,通常包括数组、元素个数、装载因子...

    希哈表C源代码工程hashtable

    常见的冲突解决策略有开放寻址法和链地址法。开放寻址法是在冲突时寻找下一个空位置;链地址法则是每个数组元素都链接一个链表,相同散列值的数据项存储在同一个链表中。 3. **动态调整大小**:当哈希表的负载因子...

    通用型哈希表HashTableT

    处理冲突的方法有多种,例如开放寻址法、链地址法、再哈希法等。 3. **动态扩容**:哈希表的大小通常是固定的,但随着键值对的增加,可能会达到容量极限。此时,哈希表需要进行扩容,通常采用双倍扩容策略,以保持...

    12 HashTable.zip

    常见的解决策略有开放寻址法(线性探测、二次探测、双哈希探测等)和链地址法(每个槽位是一个链表,冲突的元素添加到链表中)。 3. **装载因子**:装载因子是哈希表中已存储元素数量与总槽位数的比值,它直接影响...

    第9讲 对比Hashtable、HashMap、TreeMap有什么不同?1

    在面试中,HashMap的设计和实现细节是常见的考察点,例如哈希冲突的解决策略(开放寻址法和链地址法)、负载因子的影响、扩容机制以及树化改造的过程。当HashMap的桶内元素过多时,会将链表转化为红黑树,以优化查找...

    JAVASCRIPT HashTable

    常见的冲突解决方法有开放地址法(如线性探测再散列)和链地址法(即使用链表存储冲突的元素)。 #### 三、JavaScript实现哈希表 根据提供的代码片段,我们可以看到一个简单的哈希表实现方式: ```javascript ...

    基于哈希技术与MapReduce的大数据集K-近邻算法实现代码

    哈希碰撞(两个不同的输入得到相同的哈希值)是哈希表的主要问题,解决方法包括开放寻址法、链地址法和再哈希法等。在KNN算法中,哈希可以用来快速定位邻居候选集,降低计算复杂度。 **MapReduce** MapReduce是由...

    C++数据结构实现之HashTable.zip

    常见的冲突解决策略有开放寻址法、链地址法和再哈希法等。 1. **开放寻址法**:当发生冲突时,寻找下一个空的哈希地址,直到找到为止。这种方法可能导致聚集现象,影响性能。 2. **链地址法**:每个数组元素存储一...

    02. Dr Ahmed Khattab_hashtable_sortingAlgorithm_binarysearchtree

    哈希冲突是哈希表面临的一个挑战,解决方法包括开放寻址法和链地址法。理解哈希表的原理和设计良好的哈希函数对于编写高效的数据存储和检索程序至关重要。 **排序算法** 是用于重新排列数据序列以按特定顺序排列的...

    算法面试通关40讲完整课件 14-17 哈希表(HashTable)

    解决冲突有多种策略,如开放寻址法、链地址法、再哈希法等。在实际应用中,比如Java的HashMap和C++的std::unordered_map,它们通常使用链地址法,即在每个哈希桶内维护一个链表或红黑树来存储冲突的元素。 3. **...

    哈希表查找(C语言实现)

    冲突是指两个不同的关键字经过哈希函数计算后得到相同的索引,解决冲突的方法有开放寻址法、链地址法、再哈希法等。 二、哈希表查找的工作原理 1. **哈希函数**:哈希函数是哈希表的核心,它负责将关键字转化为数...

    HashTable:HashTable 的不同实现

    由于碰撞(两个不同的键映射到同一个位置)的可能性,通常还需要配合链表或开放寻址法等解决冲突的方法。 2. **`HashTable`类概述**: `HashTable`在Java中是线程安全的,这意味着在多线程环境下,它能保证数据的...

    leetcode答案-LeetCode--HashTable:LeetCode--哈希表

    常见的冲突解决策略有开放寻址法和链地址法。 1. 开放寻址法:当发生冲突时,通过特定的探测序列寻找下一个空的数组位置。比如线性探测、二次探测和双哈希探测等。 2. 链地址法:在每个数组元素的位置上挂接一个...

    哈希表java实现及简单演示

    处理冲突有多种策略,如开放寻址法、链地址法、再哈希法等。在这个演示程序中,描述中提到的“处理冲突的方法都相对简单”,可能意味着使用了最常用的链地址法。在链地址法中,每个数组位置上都连接着一个链表,当新...

Global site tag (gtag.js) - Google Analytics