当前位置: 首页 > news >正文

Java 哈希表

在用树实现集合时,我们发现每次找数据都要比较很多次,太慢了。有没有说明方法能不用比较直接找到呢?哈希方法可以。

1.哈希表的介绍

哈希表又叫散列表,是通过哈希函数建立的一个数据结构。

哈希函数是什么呢?

举个例子:

我们定义一组数据{1,5,6,8,7,9};

此时哈希函数是:hash(key) = key % capacity(capacity为存储元素底层空间总的大小)。

2.冲突

还是上面的例子,如果在数据中加入了15,我们发现有问题。因为hash(15)=5跟hash(5)冲突了。对于这种用不同的 key 值,但得到了相同的哈希地址的现象我们叫冲突。

遇见冲突我们要想办法解决这个问题的,这里要明白一点,由于我们给的底层存储空间是有限的,永远无法满足所有情况,因此冲突是无法避免的,我们能做的是降低冲突率。

在哈希函数设计时,我们有几种解决方案:

1.直接定制法:在数据范围已知的情况下使用,且查找的范围比较小且连续,如:存26个字母。函数:hash(key) =  A*key + B;

2.除留余数法:地址数为m,取一个不大于m,但最接近或者等于m的质数p作为除数。哈希函数:hash(key) = key%p;

3.取满法:仅适用于做算法题中,就是直接取到给定数据范围的最大值。

 3.负载因子

先看一下网上的说法:HashMap 负载因子( load factor),也叫做扩容因子和装载因子,它是 HashMap 在进行扩容时的一个阈值,当 HashMap 中的元素个数超过了容量乘以负载因子时,就会进行扩容。默认的负载因子是 0.75,也就是说当 HashMap 中的元素个数超过了容量的 75% 时,就会进行扩容。

关于为什么负载因子是0.75,现在没有什么官方解释。

4.开散列(哈希桶)

开散列法又叫拉链法,名字通俗易懂,其结构就跟拉链一样,数组内存的是链表头节点的地址。

代码的模拟实现:

public class HashBucket {static class Node {public int key;public int val;public Node next;public Node(int key, int val) {this.key = key;this.val = val;}}public Node[] array = new Node[10];public int usedSize;public static final double DEFAULT_LOAD_FACTOR = 0.75f;public void push(int key,int val){int idx=key% array.length;//先判断key是否存在Node cur=array[idx];while(cur!=null){if(cur.key==key){cur.val=val;return ;}cur=cur.next;}//如果不存在Node node=new Node(key, val);node.next=array[idx];array[idx]=node;usedSize++;//看看要不要扩容if(doLoadFactor()>=DEFAULT_LOAD_FACTOR){resize();}}private double doLoadFactor(){//求当前负载因子的值return usedSize*1.0/ array.length;}private void resize(){//建立一个新的数组Node[] newArray = new Node[2*array.length];for (int i = 0; i < array.length; i++) {//遍历每一个节点,把节点分到新的数组里Node cur = array[i];while (cur != null) {int idx = cur.key % newArray.length;Node curN = cur.next;cur.next = newArray[idx];newArray[idx] = cur;cur = curN;}}array = newArray;}public int getVal(int key){int idx=key% array.length;Node cur=array[idx];while(cur!=null){if(cur.key==key){return cur.val;}cur=cur.next;}return -1;}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 如何在Linux上使用Ansible自动化部署
  • NOI大纲——普及组——素数筛法
  • CentOS搭建Apache服务器
  • 【深度学习】yolov8-det目标检测训练,拼接图的分割复原
  • 网络安全防御【IPsec VPN搭建】
  • 环信+亚马逊云科技服务:助力出海AI社交应用扬帆起航
  • Python3网络爬虫开发实战(3)网页数据的解析提取
  • SSIS_SQLITE
  • 【数据结构--查找】
  • 【反证法】932. 漂亮数组
  • 使用php adodb5连接人大金仓数据库
  • 揭秘Django与Neo4j:构建智能知识图谱的终极指南
  • Adam 和 RMSprop优化算法
  • 每日任务:HTTP状态码详解及强缓存与协商缓存的区别
  • EXO-chatgpt_api 解释
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 2017-09-12 前端日报
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • eclipse(luna)创建web工程
  • Facebook AccountKit 接入的坑点
  • Fastjson的基本使用方法大全
  • go append函数以及写入
  • iOS编译提示和导航提示
  • Java 23种设计模式 之单例模式 7种实现方式
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • node.js
  • REST架构的思考
  • Spring声明式事务管理之一:五大属性分析
  • 包装类对象
  • 闭包--闭包之tab栏切换(四)
  • 第2章 网络文档
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 记录:CentOS7.2配置LNMP环境记录
  • 面试总结JavaScript篇
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 树莓派 - 使用须知
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • 走向全栈之MongoDB的使用
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • HanLP分词命名实体提取详解
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​14:00面试,14:06就出来了,问的问题有点变态。。。
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • #HarmonyOS:Web组件的使用
  • #Linux(帮助手册)
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (5)STL算法之复制
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • (待修改)PyG安装步骤
  • (二)丶RabbitMQ的六大核心
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (简单) HDU 2612 Find a way,BFS。
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (详细文档!)javaswing图书管理系统+mysql数据库