HashTable的简单实现(不含红黑树)

先创建一个泛型类:

class HashBuck<K,V>{

//K是关键字,V是值


}

定义一个哈希桶的底层节点:

class HashBuck<K,V>{
    public static class Node<K,V>{
        K key;
        V val;
        Node<K,V> next;
        public Node(K key,V val){//构造方法
            this.key=key;
            this.val=val;
        }
    }

    double LoadFactor=0.75;//负载因子,大小可以自己决定,不能太大

    int useSize;//当前哈希表容量,默认是0

    public Node<K,V>[] array=(Node<K,V>[])new Node[10];//用array来管理哈希表,默认长度是10

   public void put(K key,V val){//要实现的方法
    }

    public V get(K key){//要实现的方法
    }


}

然后就是实现两个重要方法

public void put(K key,V val){
}
和
public V get(K key){
}

先从get方法开始:

  public V get(K key){

     int hash=key.hashCode();//调用key自己的hashCode(),获得hash
     int index=hash% array.length;//通过哈希函数,得到哈希地址
        
        Node<K,V> cur=array[index];
        while(cur!=null){
            if(cur.key.equals(key)){//通过key自己的equals方法,判断关键字是否一致,一致返回val
                return cur.val;
            }
            cur=cur.next;
        }
        return null;//遍历完都没有发现,返回空
    }

注意:代码中key调用了equals()和hashCode()方法。

所以,key关键字,如果是自定义类型,一定要重写equals()和hashCode()方法。

put()方法:

 public void put(K key, V val) {

        int hash = key.hashCode();//得到关键码
        int index = hash % array.length;//获取哈希地址
        Node<K,V> cur=array[index];
        
        //判断是否有相同的key,有就改正val然后返回
        while(cur!=null){
            if(cur.key.equals(key)){//改val,然后返回
                cur.val=val;
                return;
            }
            cur=cur.next;
        }
        
        //程序到这里,说明要么,没有哈希冲突,要么没有一样的key,直接创建节点,然后头插
        Node<K,V> newNode=new Node<>(key,val);
        newNode.next=array[index];
        array[index]=newNode;
        
        useSize++;
        if(useSize*1.0/array.length>=LoadFactor){//大于等于负载因子,扩容
            reSize();//我把扩容封装成一个方法    
        }

    }

reSize()方法:

    private void reSize(){

        //创建一个比array大一倍的数组
        Node<K,V>[] newArr=(Node<K,V>[])new Node[array.length*2];

        for (int i = 0; i <array.length ; i++) {//遍历原来的哈希表
            Node<K,V> cur=array[i];
            while(cur!=null){
                int hash=cur.key.hashCode();
                int index=hash%newArr.length;//重新哈希

                //头插
                Node<K,V> tmp=cur.next;//保存好下一个节点,等一下继续while遍历
                cur.next=newArr[index];
                newArr[index]=cur;
                cur=tmp;
            }
        }
array=newArr;//把新的哈希表,给到array管理

    }

在实际的底层中,如果链表的长度达到一定时,会把他们变成红黑树,比较的复杂,这里就不展示了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hashtable(哈希表)是一种常用的数据结构,它通过将键映射到桶中来实现快速查找。底层实现通常使用数组和链表(或红黑树)的组合。 具体实现如下: 1. 首先,定义一个固定大小的数组用于存储哈希表的桶,每个桶可以存储一个或多个键值对。 2. 在插入一个新元素时,先将键通过哈希函数转换为一个索引值,然后将其存储在对应的桶中。如果该桶中已经有键值对了,则需要使用链表(或红黑树)来解决哈希冲突,将新的键值对添加到链表(或红黑树)的末尾。 3. 在查找一个元素时,同样需要使用哈希函数计算键的索引值,并在对应的桶中查找。如果该桶中有多个键值对,则需要遍历链表(或红黑树)来查找对应的键值对。 4. 当哈希表中的元素数量达到一定阈值时,需要对哈希表进行扩容。扩容的过程包括创建一个新的更大的数组和将所有键值对重新插入到新的数组中。这是因为随着哈希表中元素的增加,哈希冲突的概率也会增加,为了保证哈希表的性能,需要扩容来减少哈希冲突的概率。 5. 在删除一个元素时,需要先通过哈希函数计算出键的索引值,并在对应的桶中查找该键值对。如果存在,则可以直接删除。如果该桶中有多个键值对,则需要遍历链表(或红黑树)来查找对应的键值对并进行删除。 总之,哈希表的底层实现使用了数组和链表(或红黑树)的组合,通过哈希函数将键映射到桶中来实现快速查找。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值