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");
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值