You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java线性探测哈希表:如何不通过0或null判断数组索引是否未初始化

线性探测哈希表存储0的问题解决建议

原代码的核心问题在于:int数组默认初始值为0,导致无法正确存储0——判断table[key]!=0会把未使用的位置误判为已占用,而用null判断又会因为int是基本类型报错。以下是几种可行的解决办法:

  • 使用Integer包装类数组
    把int数组换成Integer数组,未占用位置的初始值为null,可通过null判断是否空闲,存储0时Java会自动装箱为Integer.valueOf(0),不会和null混淆。修改后的代码:

    public class LinearProbing {
        private Integer table[];
        private int size;
    
        LinearProbing(int size) {
            this.size = size;
            table = new Integer[size];
        }
    
        public void hash(int value) {
            int key = value % size;
            while (table[key] != null) {
                key++;
                if (key == size) {
                    key = 0;
                }
            }
            table[key] = value;
        }
    
        public void display() {
            for (int i = 0; i < size; i++) {
                System.out.println(i + "->" + table[i]);
            }
        }
    }
    

    优点是改动最小、逻辑清晰;缺点是存在少量装箱拆箱的性能开销,多数场景下可忽略。

  • 单独维护占用状态数组
    新增一个boolean类型的occupied数组,专门标记每个位置是否被占用,初始值全为false。存储值时将对应位置的occupied[key]设为true,判断空闲只看occupied[key],和存储的int值无关。修改后的代码:

    public class LinearProbing {
        private int table[];
        private boolean occupied[];
        private int size;
    
        LinearProbing(int size) {
            this.size = size;
            table = new int[size];
            occupied = new boolean[size];
        }
    
        public void hash(int value) {
            int key = value % size;
            while (occupied[key]) {
                key++;
                if (key == size) {
                    key = 0;
                }
            }
            table[key] = value;
            occupied[key] = true;
        }
    
        public void display() {
            for (int i = 0; i < size; i++) {
                System.out.println(i + "->" + table[i]);
            }
        }
    }
    

    优点是避免了包装类的类型转换开销,逻辑直观,适合性能敏感场景;缺点是多维护一个数组,占用额外内存。

  • 使用特殊哨兵值标记空闲位置
    选择一个业务中不会用到的int值作为哨兵,比如Integer.MIN_VALUE(-2147483648),初始化数组时将所有位置设为该哨兵值,判断空闲时检查table[key] != 哨兵值,这样存储0就不会和空闲标记冲突。修改后的代码:

    public class LinearProbing {
        private int table[];
        private int size;
        private static final int EMPTY = Integer.MIN_VALUE;
    
        LinearProbing(int size) {
            this.size = size;
            table = new int[size];
            // 初始化所有位置为哨兵值
            for (int i = 0; i < size; i++) {
                table[i] = EMPTY;
            }
        }
    
        public void hash(int value) {
            int key = value % size;
            while (table[key] != EMPTY) {
                key++;
                if (key == size) {
                    key = 0;
                }
            }
            table[key] = value;
        }
    
        public void display() {
            for (int i = 0; i < size; i++) {
                System.out.println(i + "->" + (table[i] == EMPTY ? "空" : table[i]));
            }
        }
    }
    

    优点是无需额外数组,也没有包装类开销;缺点是必须确保业务数据不会用到该哨兵值,否则会出现冲突。

内容的提问来源于stack exchange,提问作者BhanuPrakashSakkuri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 23:06:27