线性探针法哈希表

2019-07-03  11:40:23

import java.io.ObjectInputStream;
import java.util.ArrayList;

/**
 * @ClassName LinearProbeHashST
 * @Author wangyudi
 * @Date 2019/7/3 10:53
 * @Version 1.0
 * @Description 用线性试探法实现哈希表
 */
public class LinearProbeHashST<Key, Value> {
    private int m; //数组大小
    private int n;//键值对数量
    private Key[] keys;//键数组
    private Value[] values;//值数组
    private ArrayList<Key> arr;//用于迭代的集合

    /**
     * 构造函数
     * 初始化数组对
     */
    public LinearProbeHashST() {
        this(16);
    }
    public LinearProbeHashST(int m) {
        this.m = m;
        this.n = 0;
        this.keys = (Key[]) new Object[m];
        this.values = (Value[]) new Object[m];
    }

    /**
     * 调整数组的大小(对于线性探针哈希表而言,该数组大小调整时必须的)
     * 需要新建一个哈希表,将源哈希表的数据PUT到新哈希表中,然后把新建符号表的成员给原表
     * @param size
     */
    private void resize(int size) {
        LinearProbeHashST<Key, Value> linearProbeHashST = new LinearProbeHashST<>(size);
        for (int i = 0; i < m; i++) {
            if (keys[i] != null) {
                linearProbeHashST.put(keys[i], values[i]);
            }
        }
        this.m = size;
        this.values = linearProbeHashST.values;
        this.keys = linearProbeHashST.keys;
    }

    /**
     * 获取散列值
     * @param key
     * @return
     */
    private int hash(Key key) {
        return (key.hashCode() & 0x7FFFFFFF) % m;
    }

    /**
     * 向哈希表中添加键值对
     *
     * @param key
     * @param value
     */
    public void put(Key key, Value value) {
        if (n > m / 2) resize(m * 2);
        int i = hash(key);
        while (keys[i] != null) {
            if (keys[i].equals(key)) {
                values[i] = value;
                return;
            }
            i = (i + 1) % m;
        }
        keys[i] = key;
        values[i] = value;
        n++;
    }

    /**
     * 根据键获取值
     *
     * @param key
     * @return
     */
    public Value get(Key key) {
        int i = hash(key);
        while (keys[i] != null) {
            if (keys[i].equals(key)) {
                return values[i];
            }
            i = (i + 1) % m;
        }
        return null;
    }

    /**
     * 从哈希表中删除键值对
     *
     * @param key
     * @return
     */
    public Value delete(Key key) {
        int i = hash(key);
        while (keys[i] != null) {//在null前遍历所有键值对

            if (keys[i].equals(key)) { //找到该键
                Value t = values[i];
                keys[i] = null;  //删除找到的键
                values[i] = null;
                i = (i + 1) % m;  //将删除键后面的键值对重新PUT到哈希表中
                while (keys[i] != null) {
                    Key k = keys[i];
                    Value v = values[i];
                    keys[i] = null; //必须置为null,不然在键的索引正好是散列值的情况下会出问题
                    values[i] = null;
                    put(k, v);
                    i = (i + 1) % m;
                }
                n--;
                if (n > 0 && n < m / 8) resize(m / 2);
                return t;
            }

            i = (i + 1) % m;
        }
        return null;//未找到该键,则返回null
    }

    /**
     * 返回迭代器
     * @return
     */
    public Iterable<Key> keys() {
        arr = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            if (keys[i] != null) {
                arr.add(keys[i]);
            }
        }
        return arr;
    }
}
public static void main(String[] args) {
    LinearProbeHashST<Integer, String> linearProbeHashST = new LinearProbeHashST<>();
    linearProbeHashST.put(12,"12..");
    linearProbeHashST.put(2,"2..");
    linearProbeHashST.put(34,"34..");
    linearProbeHashST.put(17,"17..");
    linearProbeHashST.put(55,"55..");
    linearProbeHashST.put(214,"214..");
    for(Integer i : linearProbeHashST.keys()){
        System.out.println(i);
    }
    System.out.println("===============================================");
    System.out.println(linearProbeHashST.delete(34));
    for(Integer i : linearProbeHashST.keys()){
        System.out.println(i);
    }
    System.out.println("===============================================");
    System.out.println(linearProbeHashST.get(55));
}

//结果
17
2
34
214
55
12
===============================================
34..
17
2
214
55
12
===============================================
55..

原文地址:https://www.cnblogs.com/youzoulalala/p/11125492.html

时间: 2024-12-26 08:37:49

线性探针法哈希表的相关文章

SDUT 3379 数据结构实验之查找七:线性之哈希表

数据结构实验之查找七:线性之哈希表 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 根据给定的一系列整数关键字和素数p,用除留余数法定义hash函数H(Key)=Key%p,将关键字映射到长度为p的哈希表中,用线性探测法解决冲突.重复关键字放在hash表中的同一位置. Input 连续输入多组数据,每组输入数据第一行为两个正整数N(N <= 1000)和p(p >= N的最小素数),N是

《Java数据结构和算法》- 哈希表

Q: 如何快速地存取员工的信息? A: 假设现在要写一个程序,存取一个公司的员工记录,这个小公司大约有1000个员工,每个员工记录需要1024个字节的存储空间,因此整个数据库的大小约为1MB.一般的计算机内存都可以满足. 为了尽可能地存取每个员工的记录,使用工号从1(公司创业者)到1000(最近雇佣的工人).将工号作为关键字(事实上,用其他作为关键字完全没有必要).即使员工离职不在公司,他们的记录也是要保存在数据库中以供参考,在这种情况下需要使用什么数据结构呢? A: 一种可能使用数组,每个员工

程序员,你应该知道的数据结构之哈希表

哈希表简介 哈希表也叫散列表,哈希表是一种数据结构,它提供了快速的插入操作和查找操作,无论哈希表总中有多少条数据,插入和查找的时间复杂度都是为O(1),因为哈希表的查找速度非常快,所以在很多程序中都有使用哈希表,例如拼音检查器. 哈希表也有自己的缺点,哈希表是基于数组的,我们知道数组创建后扩容成本比较高,所以当哈希表被填满时,性能下降的比较严重. 哈希表采用的是一种转换思想,其中一个中要的概念是如何将键或者关键字转换成数组下标?在哈希表中,这个过程有哈希函数来完成,但是并不是每个键或者关键字都需

哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度

一.哈希表 1.概念 哈希表(Hash Table)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构.它通过把关键码值映射到哈希表中的一个位置来访问记录,以加快查找的速度.这个映射函数就做散列函数,存放记录的数组叫做散列表. 2.散列存储的基本思路 以数据中每个元素的关键字K为自变量,通过散列函数H(k)计算出函数值,以该函数值作为一块连续存储空间的的单元地址,将该元素存储到函数值对应的单元中. 3.哈希表查找的时间复杂度 哈希表存储的是键值对,其查找的时间复杂度与元素数

哈希表线性探测

HashTable-散列表/哈希表,是根据关键字(key)而直接访问在内存存储位置的数据结构. 它通过一个关键值的函数将所需的数据映射到表中的位置来访问数据,这个映射函数叫做散列函数,存放记录的数组叫做散列表. 哈希冲突/哈希碰撞 不同的Key值经过哈希函数Hash(Key)处理以后可能产生相同的值哈希地址,我们称这种情况为哈希冲突.任意的散列函数都不能避免产生冲突. 我给大家介绍的是哈希表的线性探测,线性探测的基本思路: 1.用一个数据除以散列表的长度,余数是多少,就把这个数放在散列表下标相同

【数据结构】哈希表的线性探测算法

构造哈希表常用的方法是: 除留余数法--取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址.HashKey= Key % P. 直接定址法--取关键字的某个线性函数为散列地址HashKey= Key 或 HashKey= A*Key + BA.B为常数. 我在这里主要使用一下除留余数法Hash(key) =Key%P,(P这里是哈希表的长度)p最好是素数考虑降低哈希冲突的原因,我并没有在这上面过于追究此处哈希表长度10,见线性探测图. 哈希表经常遇到的一个问题就是哈希冲突. 哈希冲突

哈希表---线性探测再散列(hash)

//哈希表---线性探测再散列 #include <iostream> #include <string> #include <stdio.h> #include <string.h> #define m 10000 #define NULLkey -1 using namespace std; int HashTable[m]; int Hash_search( int k) { int p0, pi; p0=hash(k); //函数运算值 if(Has

数据结构和算法-数据结构-线性结构-顺序表 链表和哈希表

####################################################### """ # 线性表是最基本的数据结构之一,在实际程序中应用非常广泛,它还经常被用作更复杂的数据结构的实现基础. # 根据线性表的实际存储方式,分为两种实现模型: # 顺序表, # 链表, # 下面分别进行研究, """ ####################################################### &qu

数据结构---哈希表(散列表)

我们在Java容器中谈到:有哈希表(也称为散列表)支持的HashMap.LinkedHashSet等都具有非常高的查询效率.这其中就是Hash起的作用.顺序查找的时间复杂度为O(N) ,二分查找和查找树的时间复杂度为O(logN),而 哈希表的时间复杂度为O(1) .不过这只是理想状态,实际并不那么完美. 1.哈希表的概念和思想 哈希表是唯一的专用于集合的数据结构.可以以常量的平均时间实现插入.删除和查找. 哈希表的思想是:用一个与集合规模差不多大的数组来存储这个集合,将数据元素的关键字映射到数