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

pythons网站开发苏州网站建设开发公司

pythons网站开发,苏州网站建设开发公司,营销型网站设计网站,昆明企业网站建设公司目录 概念冲突-概念冲突-避免冲突-避免-哈希函数设计冲突-解决-闭散列冲突-解决-开散列/哈希桶冲突-避免-负载因子调节冲突-解决哈希表代码模拟实现 概念 哈希表也是为了搞笑查找设计的,查找的时间复杂度为O(1),插入的时间复杂度也为O(1) 有…

目录

  • 概念
  • 冲突-概念
  • 冲突-避免
  • 冲突-避免-哈希函数设计
  • 冲突-解决-闭散列
  • 冲突-解决-开散列/哈希桶
  • 冲突-避免-负载因子调节
  • 冲突-解决
  • 哈希表代码模拟实现


概念

哈希表也是为了搞笑查找设计的,查找的时间复杂度为O(1),插入的时间复杂度也为O(1)
有一系列手段,把要表示的元素转换到数组上,这样的转换过程,称为哈希函数
把一大串数据,通过一系列数学变换,映射到一个较小的数组中,比如把一亿的数据保存到数组int [ ] count=new int[10000]中,像这样用来表示映射关系的数组就称为 哈希表(HashMap)

冲突-概念

如果要存储的是任意整数,范围是42亿个,但是创建的保存数据的数组范围是10000个,此时必然会出现重复,
像这样两个不同的数据,映射到同一个数组下标上的情况,叫做 哈希冲突

举例:
对key来说,一个常见的hash函数的设计方式就是直接求余数
假设key的范围是 0-42亿
哈希函数:key%1w
此时 10001,20001,30001就会映射到一个下标上(下标为1)

冲突-避免

由于我们哈希表底层数组的容量往往是⼩于实际要存储的关键字的数量的,这就导致⼀个问题,冲突的发⽣是必然的,但我们能做的应该是尽量的降低冲突率

冲突-避免-哈希函数设计

哈希函数的设计有很多种方法,比较常用的是 除留余数法
方法:对键除以一个余数(取模%),得到的余数作为数组下标

针对整数来说,就可以使用除留余数
如果是针对小数,可以先转化成整数(扩大倍数),再除留余数
针对字符串,也可以转换成较大的正整数,然后再进行求余
字符串转换:字符串每个部分都是一个字符,而字符本质上就是用数字表示的

针对数字设计的哈希函数,核心就是把不同类型的数字 先转换成一个较大的正整数,然后再进行求余,得到数组下标

冲突-解决-闭散列

问题:
在这里插入图片描述

解决方案(闭散列):
当10001占用了下标为1的位置,那么20001就往数组后面找,直到找到空位置,就插入进去,30001同理,继续往后找
如果再来一个10002,此时就继续往后找空闲位置

像这样的过程叫做“线性探测”:挨着一个一个的往后找空闲位置
还可以“二次探测”:按照1,4,9,16的长度跳着往后找

在实际开发中,“开散列”比闭散列更有价值

冲突-解决-开散列/哈希桶

使用 开散列的方法,能确保哈希函数计算出来的下标是准确位置
方法:数组的每一个元素都是“链表节点”,在有冲突的位置使用一个链表,保存“冲突”的元素

计算 哈希函数,还是O(1)
如果进行 查找/ 删除 ,可能会遍历链表,此时时间复杂度仍为O(1)
原因:可以通过一些手段,限制链表的最大长度(虽然是链表,但是长度很短,可控 [自定义的常数] )
这个最大长度,可以参考负载因子设计

冲突-避免-负载因子调节

设计 负载因子= 整个哈希表保存的元素个数 / 数组长度
负载因子的大小就相当于链表的平均长度

在实践中,可以根据 负载因子 设计 阈值
随着哈希表中元素个数的增加,使得负载因子增加,当负载因子达到阈值,就自动触发 扩容 操作 ,这样数组长度增加,负载因子又回到平均水平,这样就保证了链表平均长度不会变很大

对于Java标准库的HashMap 来说,还有一些额外的优化手段
负载因子达阈值触发 扩容 本身就有一定成本(会涉及大量的元素拷贝)
还可能触发一些极端情况(如整体链表平均长度不是很长,在阈值之下。但是个别的链表长度特别长【小概率】)
在这里插入图片描述
为了避免这样的情况,Java的 HashMap 会在元素往链表上插入的时候做一个判定,判定如果当前链表的长度达到了一定的值了,直接把链表转成红黑树(增加效率)
在这里插入图片描述
问:上述 HashMap 中,负载因子达到多少,要出发扩容?链表长度达到多少转成红黑树?
HashMap 标准库中,要求0.75 就要触发扩容

冲突-解决

哈希表 本质上是利用数组下标操作比较高效的特点 实现的一个数据结构
通过哈希函数 把要保存的内容映射到数组下标上,如果出现冲突,再通过开散列的方式来解决冲突

引入负载因子 限制链表的平均长度,保证最终的复杂度仍然是O(1)级别

哈希表代码模拟实现

  private static class Node {private int key;private int value;Node next;public Node(int key, int value) {this.key = key;this.value = value;}}private Node[]  array;private int size;   // 当前的数据个数public int HashCode(int key){//根据key得到数组下标return key%array.length;}//添加 或者 如果键相同,就修改值public void put(int key, int value) {//先判断这个键有没有存在int index=HashCode(key);Node head=array[index];for (Node cur=head;cur!=null;cur=cur.next){if(cur.key==key){cur.value=value;}}//如果没有重复key,就添加,用头插的方式Node newNode=new Node(key, value);newNode.next=head;array[index]=newNode;size++;//扩容if((double) size/array.length>0.75){resize();}}private void resize() {//扩容操作Node[] newArray=new Node[array.length*2];//新数组的长度for (int i=0;i<array.length;i++){//遍历整个数组for(Node cur=array[i];cur!=null;cur=cur.next){//针对每个下标的链表转移Node newNode=new Node(cur.key,cur.value);//获取新值int newIndex=cur.key%newArray.length;//获取新下标//插入新数组(头插)newNode.next=newArray[newIndex];newArray[newIndex]=newNode;}}array=newArray;}//根据键获取值public int get(int key) {int index=HashCode(key);for (Node cur=array[index];cur!=null;cur=cur.next){if(cur.key==key){return cur.value;}}//没找到就返回-1return -1;}//删除键值对public void remove(int key){int index=key%array.length;if(array[index]==null){//该键值对不存在return;}if(array[index].key==key){//下标的第一个元素就是该key,直接删除array[index]=array[index].next;return;}//接下来是一般情况,即键值对在链表中,删除是把前一个节点的指向指到该键值对的后面Node prev=array[index];Node cur=array[index].next;while (cur!=null){if(cur.key==key){prev.next=cur.next;size--;//删除成功return;}//如果没找到就继续往后遍历prev=cur;cur=cur.next;}}

什么时候用TreeMap,什么时候用HashMap?
绝大多数情况下,都是用HashMap,但是如果追求有序的内容,就用 TreeMap
TreeMap 使用迭代器/ foreach 进行中序遍历,得到的结果就是有序的

http://www.dtcms.com/wzjs/531060.html

相关文章:

  • seo百度站长工具汕头网站建设技术外包
  • 用dw软件做网站栅格系统好123上网主页
  • 上海网站建设网页制作怎么样友链购买有效果吗
  • 中咨城建设计有限公司官方网站互联网营销案例分析
  • 如何做jquery音乐网站推广项目
  • 做ppt网站动态网上销售平台
  • 网站建设考虑企业品牌推广营销方案
  • 做门户网站那个系统好深圳seo招聘
  • 做任务赚钱网站源码微信怎么推广自己的产品
  • app开发公司 上海长沙seo霜天
  • 做网站也是一门技术电脑系统优化软件十大排名
  • 做门户网站用什么软件昆明百度推广开户费用
  • 织梦网站怎么做伪静态域名备案
  • 上海手机网站制作公司百度建站云南服务中心
  • 怎么再各网站上做宣传品牌词优化
  • 怎么说服企业做网站市场营销策略
  • 网站前端开发语言青岛百度推广多少钱
  • 多用户自助建站系统重庆seo
  • 重庆门户网站华龙网陕西seo公司
  • 网站查询功能是用什么程序做的比较好的友链平台
  • 网站开发毕业设计开课题目推广普通话宣传语
  • 广场手机网站模板31省市新增疫情最新消息
  • 做网络兼职网站有哪些网络推广与营销
  • 个人网站备案名称填写的注意事项黄石seo
  • 青岛全网营销推广seo外包是什么
  • WordPress写文章本地上传优化大师班级
  • 做公司 网站b站2020推广网站
  • 东莞模板建站平台图片优化是什么意思
  • 佛山企业网站建设流程挖掘关键词的工具
  • 网站标准规范建设湖南seo优化排名