第二个算法作业的设计与实现。做的感觉不是很漂亮,希望大家在看完之后能给一些建议,互相学习。


任务要求:任务要求:实现OPEN 哈希表模板类(不得使用C++或JAVA自有的哈希表类)。用哈希表实现一个英语词典(1000个词,在第三个实验中使用)


算法思想:

哈希表也是一种数据结构,它能提供快速的插入和查找的功能。它是基于数组存储数据,因此,它继承了数组的比较好的一个优点,即能在O(1)时间内定位数据。同时,它也有着数组不具有的另一个优点,即对于插入删除操作,它不需要移动大量数据。而它的缺点也很明显,在数组创建后容量固定,如果数据多了之后,我们需要不断扩充容量。

哈希表的存储结构是D(数据元素集)到M(表地址集)的映射,一般的查找方法都是基于关键字比较进行的,所以导致需要定位一个数据元素的位置时,需要做大量的比较。而哈希表的算法思想是通过一种可以直接计算的方式,对于已给定的数据元素key,直接算出key在表中的位置,这样我们的查找就不必进行关键字的比较。

设计思路:

首先我们需要定义一个符合我们自己实际情况的数据类型,按照题目要求,我们的数据类型要存储字符串类型的单词,这个数据结构也应提供初始化函数以及向外部提供我们存储的数据的方法。然后,我们还要设计一个我们自己的哈希表模板类MyHashTable,类中应该包含hash数组,数组长度,初始化函数,哈希函数,增删查三种操作,以及方便我们打印结果的函数。

程序代码:


自定义的数据类型:

package HashTemplateImpl;/****@ClassName DataItem.java*@author Leno E-mail:cliugeek@us-forever.com*@date 2017年11月28日下午10:21:03*@Description 自定义数据类型*/public class DataItem {private Object iData;                   //关键字public DataItem(Object initData){      //构造器this.iData = initData;      }public Object getKey(){                 //获取关键字return iData;}
}

哈希表模板类的实现:

package HashTemplateImpl;/****@ClassName MyHashMap.java*@author Leno E-mail:cliugeek@us-forever.com*@date 2017年11月28日下午9:58:53*@Description 哈希表模板类实现*/public class MyHashTable {DataItem[] hashArray;int arraySize;// 定义数组长度public MyHashTable(int size) {// 构造器,初始化arraySize = size;hashArray = new DataItem[arraySize];}// 哈希函数public int hash(String key) {int h = 0;for (int i = 0; i < key.length(); i++)h = 31 * h + key.charAt(i);return h % arraySize;}// 插入,这里假设是数组未满,即不能插入大于arraySize的数据数public void insert(DataItem item) {Object key = item.getKey();String A = key.toString();int hashCode = hash(A);// 若已存在同样的数据,则向下进一位,直到找到空的位置// 为了简单,也可要求不准有重复数据while (hashArray[hashCode] != null) {++hashCode;hashCode %= arraySize;}hashArray[hashCode] = item;}// 删除public DataItem delete(DataItem item) {String key = item.getKey().toString();int hashCode = hash(key);while (hashArray[hashCode] != null) {if (hashArray[hashCode].getKey().toString().equals(key)) {DataItem temp = hashArray[hashCode];hashArray[hashCode] = null;return temp;}++hashCode;hashCode %= arraySize;}return null;}// 查找public DataItem find(DataItem item) {String key = item.getKey().toString();int hashCode = hash(key);while (hashArray[hashCode] != null) {if (hashArray[hashCode].getKey().toString().equals(key))return hashArray[hashCode];++hashCode;hashCode %= arraySize;}return null;}// 列出全部数据public void show() {for (int i = 0; i < arraySize; i++) {if (hashArray[i] != null)System.out.print(hashArray[i].getKey() + " ");elseSystem.out.print("* ");}System.out.println();}public static void main(String[] args) {  MyHashTable ht = new MyHashTable(10);  ht.insert(new DataItem("A"));  ht.insert(new DataItem("B"));  ht.insert(new DataItem("C"));  ht.insert(new DataItem("D"));  ht.insert(new DataItem("E"));  ht.show();  DataItem i = ht.find(new DataItem("C"));  System.out.println("i = "+i.getKey());  DataItem di = ht.delete(new DataItem("C"));  System.out.println("di = "+di.getKey());  ht.show();ht.insert(new DataItem("C"));ht.show();ht.insert(new DataItem(1));ht.show();DataItem f = ht.find(new DataItem(1));if(f!=null)System.out.println(f.getKey());elseSystem.out.println("找不见");DataItem d2 = ht.delete(new DataItem(1));if(d2!=null)System.out.println("d2="+d2.getKey());elseSystem.out.println("很难受");ht.show();}}

分析:

以上运行结果符合我们的预期,当第二次插入”C”的时候,程序按照依次寻找下一个空位置的方法,找到了元素”D”后边的第一个空位,当需要删除元素”C”的时候,我们根据hash函数找到第一个存放C的位置,并顺利删除掉了该位置上的数据。
该哈希模板适合元素插入不重的情况下使用,如果有相同的元素,例如本例中给的有两个相同的元素插入时,插入操作并不会有任何问题,但是删除操作存在着一定的缺陷,以测试例为例,当成功删除第一个元素C以后,如果再想删除第二个元素C,则会返回null值,在输出打印的时候便会报一个空指针的异常。其实这样的设计也是合理的,如果我们在不知道后续位置是否存在我们想要删除的值的时候,我们需要做遍历整个哈希表的操作,这样会浪费大量的资源,而遍历操作对于我们的哈希表来说,本来就是违背哈希原则的。
哈希表的插入删除查找操作的时间复杂度均为O(1)。

博客修改原因:

群众的眼睛是雪亮的,点名感谢郭嘉琪同学。

昨天提交的代码中,DataItem类中的数据只适合String类型的数据,为了让代码更贴切模板类这个说法,我想到的修改是将DataItem中的数据改为了Object类型。如果初始化一个DataItem对象,我所有的操作都是将这个对象的iData字段转化为String类型,然后根据哈希函数求出的位置,再做相应的操作。

另:

如果大家有兴趣,可以看一下哈希函数中那个for循环,里面的31是有讲究的,大家可以自行学习下选31的原理。
还有这个地方很容易出现数组越界问题,原因就是这个31太大了,经测试,当有5个字母的单词出现的时候很容易就越界了,所以建议大家改的小一点。

实现OPEN 哈希表模板类相关推荐

  1. java hash 数组_Java数组 哈希表 属性类 -解道Jdon

    数组 哈希表 属性类 动态小数据操作是WEB开发中不可避免的,这就涉及到数组 哈希表 属性类等几个功能;本文提供本人常用语法和简单解释: 一般数组定义 //定义数组catalogs public st ...

  2. Java:实现具有开放寻址冲突解析方法(如linear)的哈希表基类算法(附完整源码)

    Java:实现具有开放寻址冲突解析方法的哈希表基类算法 package com.williamfiset.algorithms.datastructures.hashtable;import java ...

  3. C++ 使用哈希表封装模拟实现unordered_map unordered_set

    一.unordered_map unordered_set 和 map set的区别 1. map set底层采取的红黑树的结构,unordered_xxx 底层数据结构是哈希表.unordered_ ...

  4. 除留余数法构造哈希表_哈希表算法原理

    基本概念 哈希表(Hash Table)是一种根据关键字直接访问内存存储位置的数据结构.通过哈希表,数据元素的存放位置和数据元素的关键字之间建立起某种对应关系,建立这种对应关系的函数称为哈希函数. 哈 ...

  5. e - 数据结构实验之查找五:平方之哈希表_leetcode算法之哈希表

    今天该来盘一盘 哈希表 这类题目 分类别解析leetcode上的一些相关的例题路,代码采用C++与python实现. 哈希表 哈希表是一种很有用的数据结构, 其作用主要是以空间换时间, 在c++中主要 ...

  6. 【C++ 包装器类 map】C++ 标准库(std)中的map结构 哈希表(unordered_map)和黑红树(map)教程

    目录标题 1. 哈希表(unordered_map)和黑红树(map)简介以及初始化 1.1 哈希表的基本介绍 1.1.1 哈希表初始化接口示例 1.1.2 哈希表的键值的注意事项 1.1.3 自定义 ...

  7. 16 BasicHashTable基本哈希表类(三)——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  8. CSP认证201509-3 模板生成系统[C++题解]:字符串处理、模拟、哈希表、引号里面有空格的字符串怎么读入

    题目分析 来源:acwing 分析: 本题采用vector< string > 来读入原来模板.接下来的m行需要用到哈希表,进行模板和具体内容的映射. 遍历vector,如果找到{{,就对 ...

  9. DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台、刷题集合、问题为导向的十大类刷题算法(数组和字符串、栈和队列、二叉树、堆实现、图、哈希表、排序和搜索、动态规划/回溯法/递归/贪心/分治)总

    DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台.刷题集合.问题为导向的十大类刷题算法(数组和字符串.栈和队列.二叉树.堆实现.图.哈希表.排序和搜索.动态规划/回溯法/递归/贪心/分治)总 ...

  10. ❤️导图整理数组6:四数组的四数之和,详解Counter类实现哈希表计数,力扣454❤️

    此专栏文章是对力扣上算法题目各种方法的总结和归纳, 整理出最重要的思路和知识重点并以思维导图形式呈现, 当然也会加上我对导图的详解. 目的是为了更方便快捷的记忆和回忆算法重点(不用每次都重复看题解), ...

最新文章

  1. 深度解析 Lucene 轻量级全文索引实现原理
  2. 欧阳自远:有个性的嫦娥12345,如何不重复美国探月路?
  3. Node 中文编码 我为什么哭了
  4. 统计学习:三大奇技(1)
  5. 这 28 张精炼图,将吴恩达的 deeplearning.ai 总结得恰到好处!
  6. Kubernetes-存储卷Volume
  7. linux mysql tomcat_Linux下安装Tomcat,Linux下安装Mysql
  8. webp是什么文件格式?
  9. Revit模型轻量化方法
  10. 大家身边有没有超级自恋的人
  11. 大数据如何助力“驯服”火灾?
  12. 504 Gateway Time-out 是怎么回事?
  13. 如何查找IBM P5、6的HMC管理地址
  14. 元学习、迁移学习、对比学习、自监督学习与少样本学习的关系解读
  15. 推荐几个堪称教科书级别的 Android 音视频入门项目
  16. 【如何学习CAN总线测试】——UDS诊断测试(网络层)
  17. SSM之echarts视频-Array-专题视频课程
  18. 谈用Access数据库做服务器
  19. 查询所有修过java这门课_查询选修了“JAVA”课程的学生姓名和所在的系
  20. 安卓逆向004之修改APK的图标与名称

热门文章

  1. mac php开发集成环境,MAC OS X下php集成开发环境mamp
  2. 计算机显示不出来验证码,如何解决网页图片红叉显示不出来验证码图片没显示的电脑故障...
  3. Unity lua行为树实现(可实现rpg挂机自动战斗)
  4. k8s之常用操作命令
  5. 在电脑上如何用桌面便签进行日程管理?
  6. Scrum敏捷开发模式介绍与实践
  7. 8086CPU标志位
  8. 华为给出的测试账号里面的题
  9. 【报告分享】 2020-2021年数字内容产业趋势报告-企鹅智库 (附下载)
  10. PCBA电路板中电容MLCC失效分析-应力测试作业指导