数据结构之哈希表的分离链接法java实现
哈希表的分离链接法
原理
Hash Table可以看作是一种特殊的数组。他的原理基本上跟数组相同,给他一个数据,经过自己设置的哈希函数变换得到一个位置,并在这个位置当中放置该数据。哦对了,他还有个名字叫散列
0 | 1 |
---|---|
数据1 | 数据2 |
就像这个数组,0号位置放着数据1,1号位置放数据2
而我们的哈希表则是通过一个函数f(x) 把数据1变成0,把数据2变成1,然后在得到位置插入数据1和数据2。
非常重要的是哈希表的长度为素数最好!!
而且当插入数据大于一半的时候我们要进行扩充!!!
冲突问题产生
现在这个表就是2个数据,所以不会产生什么冲突,但是若一个数据他通过f(x)计算得到的位置也是0呢?是不是就跟数据1产生了冲突,因为数据1已经占据了这个位置,你无法进行插入操作。对不对。
所以我们该如何解决这个问题呢,诶,我们肯定是想两个都可以插入是不是,就像一个炸串一样把他串起来。如图
a b c就像一个炸串,而如何实现这个炸串就有多种方式。这里我们用线性表来实现
线性表实现
我们可以用java自带的List ArrayList等表,这边也给出单链表的实现方式。
public class MyArray<AnyType> {
我们首先得创建一个内部类用来存放数据,以及保存下个节点
class ArrayNode<AnyType>{public AnyType data;public ArrayNode<AnyType> next;public ArrayNode(AnyType data){this(data,null);}private ArrayNode(AnyType data,ArrayNode<AnyType> next){this.data=data;this.next=next;}}//save type node;
设置我们这个线性表所需要的对象,例如size和一个头节点,以及我们要进行初始化,判断这个表是否为空等。
private int theSize;//array list sizeprivate ArrayNode<AnyType> head; //head node every data behind it//init MyArraypublic MyArray(){doClear();}public void clear(){doClear();}private void doClear(){theSize=0;head=new ArrayNode<>(null);}//get size and is emptypublic int size(){return theSize;}public boolean isEmpty(){return theSize==0;}
接下来我们需要实现他的基本操作,是否包含,插入,获得以及删除。
//containpublic boolean contains(AnyType x){ArrayNode<AnyType> newNode=head;//get a new node=headwhile (newNode.next!=null) {newNode=newNode.next;if (newNode.data == x)return true;}return false;}//get the data in idx from arraypublic AnyType get(int idx){return get(idx,head).data;}private ArrayNode<AnyType> get(int idx,ArrayNode<AnyType> node){if(idx<0||idx>size())throw new IndexOutOfBoundsException();//out of lengthArrayNode<AnyType> newNode=node;//find start head.nextfor (int i = 0; i < idx; i++)newNode=newNode.next;return newNode;}//set data into arraypublic void set(AnyType x){set(x,head);}private void set(AnyType x,ArrayNode<AnyType> node){ArrayNode<AnyType> newNode=node;while (newNode.next!=null)newNode=newNode.next;theSize++;newNode.next=new ArrayNode<>(x);}//removepublic void remove(AnyType x){remove(x,head);}private void remove(AnyType x,ArrayNode<AnyType> node){if(!contains(x))return;while (node.next!=null){node=node.next;if (node.next.data==x)break;}ArrayNode<AnyType> oldNode=node.next;node.next=null;node.next=oldNode.next;}
}
哈希表实现
public class MyHashTable<AnyType>{//define the things that we need to useprivate static final int DEFAULT_SIZE = 10;private MyArray<AnyType>[] arrays;private int currentSize;
因为我实现的是学号的存储
也就是带0开头的数据 所以我用字符串
这里这个myHash就是我实现的简单哈希函数,即获得的数据字符串化,得到最后两个字符
private int myHash(AnyType x){String s=x.toString();return Integer.parseInt(s.substring(s.length()-2,s.length()));}
初始化哈希表,设置的默认大小为10,然后进行素数判断,如果它不是素数,那么就找到他的下一个素数作为表的大小。
//init we should ensure that the table size is primepublic MyHashTable(){ensureTable(nextPrime(DEFAULT_SIZE));makeEmpty();}private void ensureTable(int x){arrays=new MyArray[x];for (int i = 0; i < arrays.length; i++)arrays[i]=new MyArray<>();}//make the array emptypublic void makeEmpty(){currentSize=0;for(MyArray<AnyType> myArray:arrays)myArray.clear();}//size and emptypublic int size(){return currentSize;}public boolean isEmpty(){return currentSize==0;}
基本方法的实现,插入,获得,删除,包含
//contain xpublic boolean contains(AnyType x){int position=myHash(x);return arrays[position].contains(x);}//insert xpublic void insert(AnyType x){int position=myHash(x);if(arrays[position].contains(x))return;else if(arrays[position].size()==0)if(++currentSize>arrays.length)makeBigger();arrays[position].set(x);}//get idx datapublic MyArray<AnyType> get(int idx){ return arrays[idx];}
在这里,如果插入的时候啦,实际的currentSize大于二分之一表的大小了
则进行扩充表
一般扩充表的话,我们是直接两倍两倍扩充的。
//makeBiggerpublic void makeBigger() {MyArray[] oldArray = arrays;arrays = new MyArray[2 * arrays.length];for (int i = 0; i < oldArray.length; i++)arrays[i] = oldArray[i];}
下一个素数查找,如果他是偶数,则给他加1这样可以大大减少开销。
然后进行下一个素数判断,奇数当中找素数。
//nextPrimeprivate int nextPrime(int i){if(i%2==0)i++;for (; !isPrime(i); i+=2);//ensure i is jishureturn i;}
是否为素数判断,如果为2则范围true
如果是1或者为偶数则返回false
都不满足则从三开始,他的平方小于输入的数,用奇数进行操作,因为用偶数的话,前面那个2就直接判断了,所以我们用奇数,大大减少开销。
我们也可以设置他的判断条件是小于输入的二分之一,但是我们用平方进行判断大大减少了开销,而且对于奇数来说是十分有效果的。
//is Primeprivate boolean isPrime(int i){if(i==2||i==3)return true;if(i==1||i%2==0)return false;for (int j = 3; j*j<=i ; j+=2)if (i%j==0)return false;return true;}
}
测试
public class test {public static void main(String[] args) {MyHashTable<String> a=new MyHashTable<>();a.insert("001");a.insert("01");for(int i=1;i<a.get(1).size()+1;i++){System.out.println(a.get(1).get(i));}}
}
结果
数据结构之哈希表的分离链接法java实现相关推荐
- 【数据结构笔记40】哈希表冲突处理方法:开放地址法(线性探测、平方探测、双散列、再散列),分离链接法
本次笔记内容: 11.3.1 开放定址法 11.3.2 线性探测 11.3.3 线性探测-字符串的例子 11.3.4 平方探测法 11.3.5 平方探测的实现 11.3.6 分离链接法 文章目录 冲突 ...
- C++八股文分享---数据结构其二---哈希表
C++八股文分享-数据结构其二-哈希表 前言 什么是哈希表? 搜索二叉树对值的查找是通过从根节点开始,逐个节点与目标值做比较,向下查找,直至找到目标值或是到达根节点未查找到,时间复杂度为O(logn) ...
- 【数据结构】哈希表的概念及应用
[数据结构]哈希表的概念及应用 前言 1.写出哈希表的基本概念 2.列出常用的哈希函数构造方法,并阐述各自的特点. 直接定址法 除留余数法 数字分析法 其他构造整数关键字的哈希函数的方法: 平方取中法 ...
- 「Redis数据结构」哈希表(Dict)
「Redis数据结构」哈希表(Dict) 文章目录 「Redis数据结构」哈希表(Dict) @[toc] 一.概述 二.结构 三.哈希冲突 四.链式哈希 五.rehash 六. 渐进式 rehash ...
- 用c语言实现基本数据结构(哈希表)
用c语言实现基本数据结构(哈希表) 写这个哈希表总是段错误,找了半天的bug...原来是各种小错误不断,写得很蛋疼. 我是是用数组实现的,数组的最大值定义成的宏.一共只有四个函数,分别为初始化哈希表, ...
- 图书馆管理系统(C、数据结构、哈希表、文件IO)
目录 技术路线 实现效果展示 程序主体 1.头文件部分 2.自定义函数定义部分 3.main函数部分 注意 技术路线 数据结构.哈希表.文件IO 通过C语言进行程序设计,有用到数据结构中的哈希表,通 ...
- Python与数据结构[4] - 散列表[1] - 分离链接法的 Python 实现
分离链接法 / Separate Chain Hashing 前面完成了一个基本散列表的实现,但是还存在一个问题,当散列表插入元素冲突时,散列表将返回异常,这一问题的解决方式之一为使用链表进行元素的存 ...
- 6-23 分离链接法的删除操作函数 (20 分)
试实现分离链接法的删除操作函数. 函数接口定义: bool Delete( HashTable H, ElementType Key ); 其中HashTable是分离链接散列表,定义如下: type ...
- 分离链接法的删除操作函数
习题5.11 分离链接法的删除操作函数 (20 分) 试实现分离链接法的删除操作函数. 函数接口定义: bool Delete( HashTable H, ElementType Key ); 其中H ...
最新文章
- Python 与 Excel结合
- Jmeter实现WebSocket协议的接口和性能测试方法
- EM算法和GMM(上)
- Hadoop 2.0.0-alpha尝鲜安装和hello world
- linux Swap交换分区概念
- 微博短视频千万级高可用、高并发架构如何设计?
- java地图图表动态亮点,可视化图表行动指南:地表最强解读来了
- Android 系统(14)---SystemServer进程启动过程
- shell常用的命令
- 独木舟上的旅行(贪心)
- Matlab箱线图Boxplot横坐标x轴设置
- OSS重磅推出OSS Select——使用SQL选取文件的内容
- css里禁用样式,禁用某些元素的CSS样式
- js 计算当前时间到下个整点时间,差多少分钟,多少秒
- 《WiscKey: Separating Keys from Values in SSD-conscious Storage》阅读笔记
- Unity Blend命令
- 国外变电站3d可视化技术发展_从裸眼3D技术看LED显示的发展趋势
- ps aux指令詳解 http://blog.csdn.net/hanner_cheung/article/details/6081440
- 服务器怎么增加独立显卡,dell服务器设置独立显卡(dell服务器加显卡)
- 【PMAC学习笔记——第0篇】初识PMAC运动控制卡以及 Microsoft Visual C++ 2019,PeWin32 PRO2环境搭建