在学习数据结构课程时,老师布置的一次录屏作业,以下内容是本次学习中的思路过程。

文章目录

  • 题目描述
  • 草稿记录->发现问题
  • 解决问题
  • 编写代码
  • 总结

题目描述

【问题描述】
设哈希(Hash)表的地址范围为0~17,哈希函数为:H(K)=K MOD 16,K为关键字。
用链接法进行处理冲突。
输入11个大于0的整数作为关键字序列,构造出Hash表
之后对输入的数据在表中查找
输出其地址和比较次数(若不在表中,地址值为-1)。

【输入形式】
11个数的整数序列,用空格隔开
要查找的整数

【输出形式】
地址和比较次数(若不在表中,输出-1和比较次数),用空格隔开

【样例输入】
10 24 32 17 31 30 46 47 40 63 49
63

【样例输出】
15 3(尾插法)
15 1(头插法)

草稿记录->发现问题

个人认为,先画个图理解一下最终的效果,通过笔算理清思路,是很有必要的。
本人针对构建Hash表的思路如下图所示。

整理构建Hash表的思路

整理后发现构建一个Hash表所需的行为包括:

  • 构建Hash表
  • 取关键字
  • 求关键字在Hash表中的位置
  • 根据求得的位置插入在Hash表相应位置的后面

由此,我有一个疑问。
Q:需要怎样的数据结构才能满足Hash表的要求?

解决问题

搜集的资料
为了解决上述疑问,本人搜集了关于散列表的基础知识、用链接法实现散列表、散列表的概念,散列表的实验报告等相关文章。
最终,整理出了几份构建散列表的数据结构。

typedef struct _HashNode//哈希节点
{int key;//值_HashNode* pNext;//指向下一个节点的值
}HashNode;typedef struct _Hash
{HashNode* pElement;//数据元素的存放空间
}Hash;
typedef struct MapData
{int             key;struct MapData* next;
}*MapData;typedef struct HashMap
{int             size;MapData*        data;
}*HashMap;
//二级指针
struct lNode
{int data;lNode *next;
};main(){lNode **arr = new lNode*[16];
}
typedef struct hash_arr
{int data = -1;struct hash_arr *next;struct hash_arr *prev;
} hash_arr;main()
{int a[11] = {10,24,32,17,31,30,46,47,40,63,49};hash_arr *hash_node[17];
}

最终,得到了五头雾水。。。。。

但功夫不负有心人,最终在搜集到的资料中,看到了这样一段话。

采用链地址法,其中的所有同义词构成一个单链表, 再由一个表头结点指向这个单链表的第一个结点。 这些表头结点组成一个一维数组,即哈希表。
数组元素的下标对应由散列函数求出的散列地址。

因此,本人对疑问的解答如下所示
要满足Hash表的数据结构,就得符合以下条件。

  • 能访问Hash表中所有的地址。
  • 能访问链接在各个地址后面的所有节点。

其中,节点是Hash表数据结构中的最小单位。

思路一
因为,节点是Hash表数据结构中的最小单位。
所以,表头结点就是组成Hash表数据结构的成分。
因此,可以定义两个结构体

typedef struct _HashNode //节点
{int key;struct _HashNode* pNext;
}hashNode;
typedef struct _HashTable   //Hash表头节点数组
{hashNode*  pElement;
}hashTable;

思路二
本人还不太确定,先将想法贴上。
各个节点组成了最终的Hash表。
(即由许多个一维单链表组成了链接起来的二维链表。)【由线-> 面】
根据搜集资料中的二级指针,由感而发。

编写代码

根据在草稿记录部分整理出的基本步骤与题目要求,得到以下行为。

  • 构建Hash表
  • 取关键字
  • 求关键字在Hash表中的位置
  • 根据求得的位置插入在Hash表相应位置的后面
  • 根据关键字在Hash表中查找相应的位置
#include <iostream>
#include <memory.h>
#define HASH 16using namespace std;class HashTable{
//数据结构
public:typedef struct _HashNode{int key;struct _HashNode* pNext;}hashNode; typedef struct _HashTable{hashNode*  pElement;   }hashTable;//行为
public:void initHashTable(int hashLen);             //根据给定的长度初始化Hash表,本题0~17 //构建Hahs表 void createHashTable(int keyLen);         //根据给定的键值域长度创建Hash表,在函数中实现数据的录入与插入 void insertKey(int key);                  //将键值与Hash表中的相应位置进行匹配,完成插入//根据所给值构建HashNode int calHash(int key);                        //通过键值计算Hash表中的相应位置 //查找int searchKey(int key);                     //返回查找的次数,在函数中给出查找结果并打印//输出Hash表void showHash();                         //显示数据
//属性
private:hashTable MyHashTable;int HashLen;int KeyLen;
};int main(void){HashTable hashOperate;int hashLen;int keyLen;int count;int key;cout << "设置Hash表长:";cin >>  hashLen;hashOperate.initHashTable(hashLen);cout << "设置key域大小:";cin >> keyLen;hashOperate.createHashTable(keyLen);hashOperate.showHash();cout << "待查找的键:";cin >> key;cout << hashOperate.searchKey(key) << endl;return  0;
}//根据给定的长度初始化Hash表
void HashTable::initHashTable(int hashLen){HashLen = hashLen;MyHashTable.pElement = new hashNode[hashLen];//开辟存放数组元素空间
/*for(int i=0;i<hashLen;i++){MyHashTable.pElement[i] = NULL;}*/memset(MyHashTable.pElement, 0x00, sizeof(hashNode)*hashLen);cout<<"初始化完成!!"<<endl;
}   //根据给定的键值域长度创建Hash表,在函数中实现数据的录入与插入
void HashTable::createHashTable(int keyLen){int key;cout<<"输入数据.....(keyLen ="<<keyLen<<")" <<endl;for(int i=0;i<keyLen;i++){cin >> key;insertKey(key);}
}int HashTable::calHash(int key){return key % HASH;
}void HashTable::insertKey(int key){int hashAddr = calHash(key);       //根据key计算在hash表中的相应位置//头插法 hashNode* pNew = new hashNode;      //新建一个结点pNew->key = key;pNew->pNext = MyHashTable.pElement[hashAddr].pNext;MyHashTable.pElement[hashAddr].pNext = pNew;
}           void HashTable::showHash(){for(int i=0;i<HashLen;i++){cout << "第" << i << ":";hashNode* pNode = &(MyHashTable.pElement[i]);pNode = pNode->pNext;while(pNode){//cout<<"|";cout << pNode->key << " ";pNode = pNode->pNext;}cout << endl;  }
}int HashTable::searchKey(int key){int hashAddr = calHash(key);int count = 0;int flag = 1;hashNode* pNode = &(MyHashTable.pElement[hashAddr]);pNode = pNode->pNext;while(pNode&&flag){if(pNode->key == key){cout<<hashAddr<<" ";flag = 0;   }count++;pNode = pNode->pNext;}if(pNode==NULL && flag){cout<<"-1 ";}return count;
}

总结

本次一共前后花费了将近5个小时。
在搜集资料与理解资料上花费了将近2个小时,在阅读时进行了一些批注与记录。这些记录也促成了本篇文章的完成。

本次解决问题的思路是

  1. 理解问题,笔算推导
  2. 搜集资料,学习他人经验
  3. 思考疑问,重点解决
  4. 临摹代码,实践动手

本篇文章还存在的问题/可改进的方向

  1. 思考”解决问题“中思路二的可行性
  2. 根据思路二编写代码,达成一题多解。

用链接法实现散列表构造和查找相关推荐

  1. 利用开放定址法实现散列表的创建、插入、删除、查找操作_快速入门数据结构:散列表(上)...

    散列表与散列算法 散列表的英文叫"Hash Table",我们平时也叫它"哈希表"或者"Hash 表",散列表用的是数组支持按照下标随机访问 ...

  2. 4021-基于链地址法的散列表的删除(C++,附思路)

    描述 请写出在散列表中删除关键字为k的一个记录的算法,设散列函数为H,H(key)=key%13,解决冲突的方法为链地址法. 输入 多组数据,每组三行,第一行为待输入的关键字的个数n,第二行为对应的n ...

  3. 【Java Swing/散列表】散列表实现电话号码查找系统——问题汇总分享

    说明:本文为我在做课设时遇到的问题汇总,解决方法多数来自网络,因深感到处搜索解决方法不易,所以做成汇总.因搜索时没有记录每个答案来源网站,如有侵权,请联系我.感谢无私分享的每一个人. 题目:设计散列表 ...

  4. 利用开放定址法实现散列表的创建、插入、删除、查找操作_散列表和IO

    散列表(也叫哈希表) 直接寻址法 取关键字或关键字的某个线性函数值为散列地址.即H(key)=key或H(key) = a·key + b,其中a和b为常数(这种散列函数叫做自身函数).若其中H(ke ...

  5. 4020-基于链地址法的散列表的插入(C++,附思路以及头插法,尾插法两种代码)

    描述 请写出在散列表中插入关键字为k的一个记录的算法,设散列函数为H,H(key)=key%13,解决冲突的方法为链地址法. 输入 多组数据,每组三行,第一行为待输入的关键字的个数n,第二行为对应的n ...

  6. 力扣242.有效的字母异位词(Java语言,排序法、散列表法)

    题目描述: 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词. 注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词. 解题思路: 思路1: ...

  7. 设计散列表实现通讯录查找系统_[源码和文档分享]利用哈希表实现电话号码查询系统...

    第一章 需求分析 1.1 问题描述 设计一个电话号码查询系统,为来访的客⼈提供各种信息查询服务. 1.2 基本要求 设计每个记录有下列数据项:电话号码.用户名.地址 从键盘输入个记录,分别以电话号码和 ...

  8. 散列表的平均查找长度

    等概率情况下查找成功平均查找长度 等概率情况下查找不成功的平均查找长度 题目要求 将关键字序列(7.8.30.11.18.9.14)散列存储到散列表中.散列表的存储空间是一个下标从0开始的一维数组,散 ...

  9. Python与数据结构[4] - 散列表[1] - 分离链接法的 Python 实现

    分离链接法 / Separate Chain Hashing 前面完成了一个基本散列表的实现,但是还存在一个问题,当散列表插入元素冲突时,散列表将返回异常,这一问题的解决方式之一为使用链表进行元素的存 ...

最新文章

  1. 多项NLP任务新SOTA,Facebook提出预训练模型BART​
  2. ARP欺骗防御工具arpon
  3. css3中transition属性详解
  4. 微信系列研究之-----资源文件保护的小把戏
  5. CTSCAPIO被教做人记
  6. rxjs里tap操作符的使用单步调试
  7. SAP Hybris Commerce启用customer coupon的前提条件
  8. python中求包含5的数_Python 内置函数 ( ) 可以返回列表、元组、字典、集合、字符串以及 range 对象中元素个数。_学小易找答案...
  9. hadoop中的9000端口代表什么_hadoop服务快速部署
  10. 东航期货模拟交易brockerid(期货公司的客户号)
  11. python如何用色度表示数值大小_python入门004数字(例程界面很清晰大小也合适)
  12. 查询数据库现在几个用户在连接
  13. 深化代理模式,Mybaits如何做到调用接口
  14. sqlite和MySQL一些常用命令_sqlite3常用命令语法
  15. 类似QQ表情的控件 EmotionContainer(原创)
  16. 数据库基础之14(MongoDB基本数据类型,数据导入导出,数据备份与恢复)
  17. 电信光纤友华PT921G,烽火HG220光猫破解关闭自带路由改桥接拨号教程
  18. 学校计算机房的制度,小学计算机房管理制度
  19. 2022爱分析・人工智能应用实践报告
  20. 接口流量突增,如何做好性能优化?

热门文章

  1. Python能在业余时间赚钱吗?
  2. js引擎渲染php,主流浏览器内核及JS引擎
  3. LightGBM,LGB
  4. 【Bash百宝箱】shell内建命令之builtin、command、caller
  5. UDP sendto频率过快导致发送丢包
  6. 精心为学弟学妹整理的 C语言/C++ 项目合集
  7. 安装Linux时grub2安装失败,尝试安装Ubuntu作为计算机唯一的操作系统时,我收到错误'grub-install/dev/sda failed'。 - Ubuntu问答...
  8. 两张表格数据匹配删除
  9. 安卓手机查看连接到热点设备的ip地址
  10. 在树莓派中Linux环境下rpm包的安装