哈希表之开放地址法

作用:
解决因为幂连乘之后的压缩可选值二产生的索引冲突问题.

一:什么是开放地址法

当冲突发生的时候,通过查找数组的一个空位,并将数值填充进去,而不再是使用哈希函数得到的数组下标,就叫做开放地址法
图1

二:代码实现

1.创建JavaBean类
public class Person {
    private String key;
    private String name;

    public Person(String key, String name) {
        this.key = key;
        this.name = name;
    }
    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

2.HashTable,使用开放地址法插入数据/查找数据/删除数据
import java.math.BigInteger;

public class HashTable {
    //数组
    private Person[] arr;

    //构造
    public HashTable() {
        arr = new Person[10];
    }
    public HashTable(int size){
        arr = new Person[size];
    }

    //开放地址发进行插入数据
    public void insert(Person person){
        //1.获取哈希函数得到的索引
        int index = hashCode(person.getKey());
        //2.如果所有被占用,而且里面存着合法数据 ,则不能插入数据
        while (arr[index] != null && arr[index].getName() != null){
            ++index;
            //3.如果所有越界了,就是index增长到大于数组长度-1的时候,需要从头开始找
            index %= arr.length;
        }
        //4.插入数据
        arr[index] = person;
    }

    //查找数据
    public Person find(String key){
        int index = hashCode(key);
        while (arr[index] != null){
            //如果key相同
            if (arr[index].getKey().equals(key)){
                return arr[index];
            }else{
                //key不同,找下一位索引的key
                ++index;
                //循环
                index %= arr.length;
            }
        }
        //找不到
        return null;
    }

    //删除数据
    public Person delete(String key){
        int index = hashCode(key);
        while (arr[index] != null){
            //如果key相同
            if (arr[index].getKey().equals(key)){
                //找到了
                Person tmp = arr[index];
                //删除数据,把name设置为null,保留key(也可以删除整个person对象,看需求而定)
                arr[index].setName(null);
                return tmp;
            }
            //累加和循环
            ++index;
            index %= arr.length;
        }
        //如果找到不到,返回null
        return null;
    }

    //字符串转化成ASCII码,并且进行幂的连乘,最后取模再返回
    //使用 BigInteger 类型代替int类型
    public int hashCode(String key){
        BigInteger hashCode = new BigInteger("0");
        BigInteger pow = new BigInteger("1");

        for (int i = key.length()-1;i>= 0 ; i--){
            BigInteger value = new BigInteger(String.valueOf(key.charAt(i) - 96));
          hashCode =  hashCode.add(value.multiply(pow));
          pow = pow.multiply(new BigInteger("27"));
        }
        //取模后再转成 int 类型返回
        return hashCode.mod(new BigInteger(String.valueOf(arr.length))).intValue();
    }
}

3.测试
public class Test {
    public static void main(String[] args) {

        HashTable hashTable = new HashTable();

        //插入数据
        hashTable.insert(new Person("a","张三"));
        hashTable.insert(new Person("ct","李四"));

        //查找
        Person person = hashTable.find("ct");
      if (person == null){
          System.out.println("找不到");
      }else{
          System.out.println(person.getName()); //李四
      }

      //删除数据
        Person person1 = hashTable.delete("ct");
        if (person1 == null){
            System.out.println("找不到被删除的key");
        }else{
            System.out.println("已删除"); //已删除
        }

        //查找
        Person person2 = hashTable.find("ct");
        if (person2.getName() == null){
            System.out.println("找不到"); //找不到
        }else{
            System.out.println(person2.getName());
        }

    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值