Algorithms-3.4 Hash Tables 散列表

1 hash functions 散列函数

在这里插入图片描述

  • 用index(0、1、2……)代表key
    在这里插入图片描述
  • 优秀的散列方法要保持一致性(等价键产生相同散列值)、高效性(计算简便)、均匀性(均匀地散列所有键)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 因为string是不能变的,因此string的hash code也不变,只需计算一次
package Chapter03;

//自定义类型中hashcode()方法的实现
public final class Transaction implements Comparable<Transaction>{
    private final String who;
    private final Date when;
    private final double amount;

    public Transaction(String who, Date when, double amount) {
        if (Double.isNaN(amount) || Double.isInfinite(amount))
            throw new IllegalArgumentException("Amount cannot be NaN or infinite");
        this.who    = who;
        this.when   = when;
        this.amount = amount;
    }

    public boolean equals(Object y){
        if (y == this) return true;
        if (y == null) return false;
        if (y.getClass() != this.getClass()) return false;//保证比较的两者在同一个类中
        Transaction that = (Transaction) y;
        return (this.amount == that.amount) && (this.who.equals(that.who))
                && (this.when.equals(that.when));
    }

    //计算hashcode,返回一个32-bit value
    public int hashCode(){
        int hash = 17;//自定义一个nonzero constant(small prime number)
        //for reference type, use hashCode()
        hash = 31 * hash + who.hashCode();//small prime number --> 31
        hash = 31 * hash + when.hashCode();
        //for primitive type, use hashCode() of wrapper type 括号包装
        hash = 31 * hash + ((Double) amount).hashCode();
        return hash;
    }


    @Override
    public int compareTo(Transaction o) {
        return 0;
    }
}

在这里插入图片描述
在这里插入图片描述

  • 将hashCode()的返回值转化为一个数组索引,因为需要的是数组的索引而不是一个32位的整数
  • 将默认的hashCode()和除留余数法结合,产生一个0~M-1的整数
  • 将符号位屏蔽(将1个32位整数变为一个31位非负整数)
  • M要选质数,以充分利用原散列值的所有位
    在这里插入图片描述
    在这里插入图片描述

2 separate chaining 基于拉链法的散列表

在这里插入图片描述
在这里插入图片描述

package Chapter03;

public class SeparateChainingHashST<Key, Value>{
    private int M = 97; //number of chains
    private Node[] st = new Node[M];//array of chains

    private static class Node{
        private Object key;
        private Object val;
        private Node next;

		//有参构造
        public Node(Object key, Object val, Node next) {
            this.key = key;
            this.val = val;
            this.next = next;
        }
    }

    private int hash(Key key){
        return (key.hashCode() & 0x7fffffff) % M;//返回0到M-1
    }

    public Value get(Key key){
        int i = hash(key);
        for (Node x = st[i]; x != null ; x = x.next) {//st[i]是一条链
            if (key.equals(x.key)) return (Value) x.val;
        }
        return null;
    }

    public void put(Key key, Value val){
        int i = hash(key);
        for (Node x = st[i]; x != null ; x = x.next) {//st[i]是一条链
            if (key.equals(x.key)) {
                x.val = val;
                return;
            }
        }
        st[i] = new Node(key, val, st[i]);//没有找到,则在原链表的最前面新建一个node
    }
}

在这里插入图片描述
在这里插入图片描述

3 linear probing 基于线性探测法的散列表

在这里插入图片描述

  • Insert
    在这里插入图片描述
  • 数组M必须比键值对的数量N大
    在这里插入图片描述
  • Search
    在这里插入图片描述
    在这里插入图片描述
package Chapter03;

public class LinearProbingHashST<Key, Value> {
    private int M = 30001;//线性探测表的大小
    private Value[] vals = (Value[]) new Object[M];
    private Key[] keys = (Key[]) new Object[M];

    private int hash(Key key){
        return (key.hashCode() & 0x7fffffff) % M;//返回0到M-1的整数
    }

    public void put(Key key, Value val){
        int i;
        for (i = hash(key); keys[i] != null ; i = (i+1) % M) {//%取余 当被除数比除数小,余数为除数
            if (keys[i].equals(key)){
                break;//立即终止离他最近的那个循环语句 不能在if语句中使用break和continue,此处的break是对for循环起作用,因此可以使用
            }
        }
        keys[i] = key;
        vals[i] = val;
    }

    public Value get(Key key){
        for (int i = hash(key); keys[i] != null ; i = (i+1) % M) {
            if (key.equals(keys[i])){
                return vals[i];
            }
        }
        return null;
    }
}

在这里插入图片描述

  • mean displacement平均位移距离
    在这里插入图片描述
    在这里插入图片描述

4 context 散列表的文本应用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值