zoukankan      html  css  js  c++  java
  • 线性探针法哈希表

    线性探针法哈希表

    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;//空位前没有找到对应的键,则返回null
        }
    
        /**
         * 从哈希表中删除键值对
         *
         * @param key
         * @return
         */
        public Value delete(Key key) {
            int i = hash(key);
         Value t = null;
    while (keys[i] != null) {//从散列值开始遍历直到遇到空位(在null前遍历所有键值对) if (keys[i].equals(key)) { //找到该键 t = values[i]; keys[i] = null; //删除找到的键 values[i] = null;
              n--; i
    = (i + 1) % m; //将删除键后面的键值对重新PUT到哈希表中
    }
    while (keys[i] != null) { //先保存键值,然后删除键值,再插入键值对 Key k = keys[i]; Value v = values[i]; keys[i] = null; //必须置为null,不然在键的索引正好是散列值的情况下会出问题 values[i] = null;
                n--; put(k, v); //会 n++ i
    = (i + 1) % m; }
    if (n > 0 && n < m / 8) resize(m / 2);return t;//未找到该键,则返回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..
  • 相关阅读:
    Failed to create the Java Virtual Machine
    图文解析进程与线程区别
    HTTP协议详解
    打开某网站无法访问出现空白页可能的原因
    子网划分举例
    上传验证绕过全解析
    Linux命令之远程登录与执行远程主机命令
    information_schema Introduction
    python多进程之multiprocessing
    python多线程之Threading
  • 原文地址:https://www.cnblogs.com/youzoulalala/p/11125492.html
Copyright © 2011-2022 走看看