【Java】哈希表 AcWing 840. 模拟散列表

简介: 【Java】哈希表 AcWing 840. 模拟散列表

一、题目

https://www.acwing.com/problem/content/842/


二、思路


拉链法

开放寻址法采用hash函数找到在hash数组中对应的位置,如果该位置上有值,并且这个值不是寻址的值,则出现冲突碰撞,需要解决冲突方案,该算法采用链表的形式,一直往下拉


开放寻址法


开放寻址法采用hash函数找到在hash数组中对应的位置,如果该位置上有值,并且这个值不是寻址的值,则出现冲突碰撞,需要解决冲突方案,该算法采用简单的向右继续寻址来解决问题。


三、代码


拉链法


import java.util.Scanner;
public class Main {
    //N:操作数量 , h[N]:拉链数组 , e[N]:地址为N的数值 , ne[N]:地址为N的下一个节点地址,index:节点地址
    static int N=100003;   static int index=1;
    static int []h=new int[N];
    static int []e=new int[N]; static int []ne=new int[N];
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n= sc.nextInt();
        while (n-->0) {
            String s=sc.next();
            int c=sc.nextInt();
            if(s.equals("I")){
                insert(c);
            }else {
                if(query(c)){
                    System.out.println("Yes");
                }else System.out.println("No");
            }
        }
    }
    private static void insert(int x) {
      int n=(x%N+N)%N;   //+N余N是为了防止取余的结果为负数
      e[index]=x;
      ne[index]=h[n];
      h[n]=index++;
    }
    private static boolean query(int x) {
        int n=(x%N+N)%N;
        for(int i=h[n];i!=0;i=ne[i]){
            if(e[i]==x) return true;
        }
        return false;
    }
}


开放寻址法


import java.util.*;
public class Main{
    private static int N = 200003;
    //因为要用null标识节点空,所以类型为Integer
    private static Integer[] a = new Integer[N];
    public static int find(int x){
        int k = (x % N + N) % N;
        //别忘了第二个已存在的条件
        while(a[k] != null && a[k] != x){
            k++;
            if(k == N){
                k = 0;
            }
        }
        return k;
    }
    public static void main(String[] args){
        //先将所有位置设为null,标识为空
        Arrays.fill(a,null);
        Scanner scanner = new Scanner(System.in);
        int m = scanner.nextInt();
        while(m-- > 0){
            String opt = scanner.next();
            int x = scanner.nextInt();
            if("I".equals(opt)){
                a[find(x)] = x;
            }else{
                //这是比较的是a[find(x)]
                System.out.println(a[find(x)] == null ? "No" : "Yes");
            }
        }
    }
}


相关文章
|
6天前
|
存储 算法 Java
[Java]散列表的数据结构以及对象在JVM堆中的存储过程
[Java]散列表的数据结构以及对象在JVM堆中的存储过程
56 1
[Java]散列表的数据结构以及对象在JVM堆中的存储过程
|
6天前
|
存储 安全 Java
【亮剑】`ConcurrentHashMap`是Java中线程安全的哈希表,采用锁定分离技术提高并发性能
【4月更文挑战第30天】`ConcurrentHashMap`是Java中线程安全的哈希表,采用锁定分离技术提高并发性能。数据被分割成多个Segment,每个拥有独立锁,允许多线程并发访问不同Segment。当写操作发生时,计算键的哈希值定位Segment并获取其锁;读操作通常无需锁定。内部会根据负载动态调整Segment,减少锁竞争。虽然使用不公平锁,但Java 8及以上版本提供了公平锁选项。理解其工作原理对开发高性能并发应用至关重要。
|
6天前
|
存储 算法 安全
【Java编程进阶之路 02】深入探索:红黑树如何重塑哈希表的性能边界
JDK 1.8之后,HashMap引入红黑树来优化性能,当链表长度超过阈值(默认为8)时,链表会转换为红黑树,从而提高高冲突时的查询效率。同时,HashMap也采用了扰动函数来增加哈希值的随机性,使键值对更均匀分布,提升性能。
39 0
|
6天前
|
存储 缓存 安全
Java ConcurrentHashMap:线程安全的哈希表实现
Java ConcurrentHashMap:线程安全的哈希表实现
|
6天前
|
存储 缓存 Java
Java LinkedHashMap:保持插入顺序的哈希表解析
Java LinkedHashMap:保持插入顺序的哈希表解析
|
6天前
|
存储 缓存 安全
Java HashMap:哈希表原理、性能与优化
Java HashMap:哈希表原理、性能与优化
|
6天前
|
存储 Java Serverless
哈希表原理与Java HashSet、LinkedHashSet实现
哈希表原理与Java HashSet、LinkedHashSet实现
|
6天前
|
存储 Java Serverless
二叉搜索树 和 哈希表 (JAVA)
【1月更文挑战第1天】阿里云初体验 二叉搜索树 二叉搜索树的插入 二叉搜索树的查找 二叉搜索树的删除 哈希表 哈希冲突 闭散列 线性探测法 二次探测法 开散列 二叉搜索树又称二叉排序树,它具有以下性质的二叉树或空树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的每颗子树也分别为二叉搜索树 而哈希表是一种插入/删除/查找时间复杂度都是O(1)的数据结构,它的查询之所以也可以如此之快的的原因就是它在查找时不需要经过任何比较,直接一次从表中得到要搜索的元素。
40 0
二叉搜索树 和 哈希表 (JAVA)
|
6天前
|
存储 缓存 Java
java如何实现一个LRU(最近最少使用)缓存? 要求:设计一个LRU缓存,支持get和put操作。当缓存满时,需要淘汰最近最少使用的元素。要求使用双向链表+哈希表的数据结构来实现,并保证get和put操作的时间复杂度为O(1)。
java如何实现一个LRU(最近最少使用)缓存? 要求:设计一个LRU缓存,支持get和put操作。当缓存满时,需要淘汰最近最少使用的元素。要求使用双向链表+哈希表的数据结构来实现,并保证get和put操作的时间复杂度为O(1)。
30 1
|
7月前
|
存储 缓存 安全
【JavaSE专栏55】Java集合类HashTable解析,基于哈希表实现的唯一性键值对存储数据结构
【JavaSE专栏55】Java集合类HashTable解析,基于哈希表实现的唯一性键值对存储数据结构