算法#14--详解各种字符串查找算法和代码实现

1.算法汇总

首先,来看一张各种字符串查找算法的汇总。前面的文章已经介绍过二叉树查找和红黑树查找。这里不在介绍。

本文重点介绍后面三种查找算法:线性探测法、R向单词查找树和三向单词查找树。

2.线性探测法

实现散列表的另一种方式是用大小为M的数组保存N个键值对,其中M>N。依靠数据中的空位解决碰撞冲突。基于这种策略的所有方法都统称为开放地址散列表。其中最简单的方法叫做线性探测法:当碰撞发生时,直接检查散列表的下一个位置(索引加1),可能产生三种结果:

  • 命中,该位置的键和被查找的键相同;
  • 未命中,键为空(该位置没有键);
  • 继续查找,该位置的键和被查找的键不同。

其核心思想是与其将内存用作链表,不如将它们作为散列表的空元素。即用散列函数找到索引,检查其中的键和被查找的键是否相同。如果不同则继续查找(增加索引,到达数组结尾后再折回数组开头),直到找到该键或者遇到一个空元素。过程如下图所示:

在基于线性探测法的散列表中执行删除操作比较复杂,如果将该键所在位置为为null是不行的。需要将簇中被删除键的右侧的所有键重新插入散列表。

代码实现


//基于线性探测的符号表
public class LinearProbingHashST<Key,Value> 
{
    private static final int INIT_CAPACITY = 16;

    private int n;// 键值对数量
    private int m;// 散列表的大小
    private Key[] keys;// 保存键的数组
    private Value[] vals;// 保存值的数组

    public LinearProbingHashST() 
    {
        this(INIT_CAPACITY);
    }

    @SuppressWarnings("unchecked")
    public LinearProbingHashST(int capacity) 
    {
        this.m = capacity;
        keys = (Key[]) new Object[capacity];
        vals = (Value[]) new Object[capacity];
    }

    public int hash(Key key)
    {
        return (key.hashCode() & 0x7fffffff) % m;
    }

    public void put(Key key, Value val)
    {
        if(key == null) 
        {
            throw new NullPointerException("key is null");
        }

        if(val == null)
        {
            delete(key);
            return;
        }

        // TODO扩容
        if(n >= m/2)
        {
            resize(2*m);
        }

        int i = hash(key);
        for (; keys[i] != null; i = (i + 1) % m) 
        {
            if(key.equals(keys[i]))
            {
                vals[i] = val;
                return;
            }
        }

        keys[i] = key;
        vals[i] = val;
        n++;
    }

    public void delete(Key key)
    {
        if(key == null) 
        {
            throw new NullPointerExcepti
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值