哈希表概念和实现,C/C++实现
body, table{font-family: 微软雅黑; font-size: 13.5pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}
散列技术既是一种存储方法,也是一种查找方法。
散列函数设计原则:简单、均匀、存储利用率高
两个关键字 key1 ≠ key2,但是却有 f(key1) ≠ f(key2),这种现象我们称为冲突(collision),并把key1和key2称为这个散列函数的同义词(synonym)。
处理散列冲突的方法
| 链地址法:将所有关键字为同义词的记录存储在一个单链表中,这种链表叫做同义词子表,使用除留余数法,就不存在冲突的问题了,只是在链表中增加一个结点。 |
公共溢出区法:
对所有冲突的关键字建立一个公共溢出区来存放
|
| | |
|
#include<iostream>
#include<stdlib.h>
#define max ~( 1<<(sizeof(int)*8-1) )
using namespace std;
//散列函数采用除留余数法
//冲突解决采用开放定址法的线性探测法
int hashFunc(int key,int length);
int initHashTable(int* hashTable,int length); //成功返回0,失败返回-1
int hashInsert(int* hashTable,int key,int length); //成功返回0,失败返回-1
static enum status{failture=-1,success=0} flag;
int hashSearch(int*hashTable,int key,int length);
void test();
int main()
{
test();
system("pause");
}
int initHashTable(int* hashTable,int length)
{
if(nullptr==hashTable || length<=0)
return -1;
for(int idx=0;idx!=length;++idx)
{
hashTable[idx] = max;
}
return 0;
}
int hashFunc(int key,int length)
{
if(key==max||length<=0)
return -1;
return key % length; //除留余数
}
int hashInsert(int* hashTable,int key,int length)
{
if(nullptr==hashTable||length<=0)
return -1;
int hashAddr = hashFunc(key,length);
if(-1==hashAddr)
return -1;
for(int idx=0;idx!=length;++idx) //循环,最大哈希表长度
{
if(hashTable[hashAddr]!=max) //冲突
hashAddr = (hashAddr+1) % 12; //开放定址法的线性探测法,查找下一个可存放数据的空间
else
break;
}
if(max==hashTable[hashAddr])
{
hashTable[hashAddr] = key;
return 0;
}
return -1;
}
|
void test()
{
int arr[12] = {12,67,56,16,25,37,22,29,15,47,48,34};
int* hashTable = new int[12]();
int ret = initHashTable(hashTable,12);
if(-1==ret)
cout<<"initHashTable fail!"<<endl;
cout<<"哈希表待插入元素:";
for(int idx=0;idx!=12;++idx)
{
cout<<arr[idx]<<" ";
hashInsert(hashTable,arr[idx],12);
}
cout<<endl;
cout<<"哈希表:";
for(int idx=0;idx!=12;++idx)
{
cout<<hashTable[idx]<<" ";
}
cout<<endl;
cout<<"对应插入元素序列在哈希表查找元素:";
for(int idx=0;idx!=12;++idx)
{
int ret = hashSearch(hashTable,arr[idx],12);
if( ret==-1 && flag == failture)
{
cout<<"search "<<arr[idx]<<" fail"<<endl;
}
cout<<hashTable[ret]<<" ";
}
cout<<endl;
cout<<"查找1:"<<endl;
int rett = hashSearch(hashTable,1,12);
if( rett==-1 && flag == failture)
{
cout<<"search "<<1<<" fail"<<endl;
return ;
}
cout<<hashTable[rett]<<endl;
}
int hashSearch(int*hashTable,int key,int length)
{
flag = success;
if(nullptr==hashTable||length<=0)
{
flag = failture;
return -1;
}
int hashAddr = hashFunc(key,length);
while(key!=hashTable[hashAddr])
{
hashAddr = (hashAddr+1) % length;
if(max==hashTable[hashAddr] || hashAddr == hashFunc(key,length)) //如果探测到下一个地址为空,还没有找到,或者循环找了一遍又回到最开始的hashAddr
{
flag = failture;
return -1;
}
}
return hashAddr;
}
|
哈希表概念和实现,C/C++实现的更多相关文章
- 哈希表(hash table)基础概念
哈希是什么 引入:我们在学习数组的时候,使用数组元素的下标值即可访问到该元素,所花费的时间是O(1),与数组元素的个数n没有关系,这就是哈希方法的核心思想. 哈希方法:以关键值K为自变量,通过一定的函 ...
- 什么叫哈希表(Hash Table)
散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. - 数据结构 ...
- Berkeley DB的数据存储结构——哈希表(Hash Table)、B树(BTree)、队列(Queue)、记录号(Recno)
Berkeley DB的数据存储结构 BDB支持四种数据存储结构及相应算法,官方称为访问方法(Access Method),分别是哈希表(Hash Table).B树(BTree).队列(Queue) ...
- 从HashMap透析哈希表
##扯数据结构 先看一下哈希表的概念: 哈希表是一种数据结构,它可以提供快速的插入操作和查找操作.第一次接触哈希表,他会让人难以置信,因为它的插入和删除.查找都接近O(1)的时间级别.用哈希表,很多操 ...
- 哈希表的C++实现(转)
哈希表的几个概念: 映像:由哈希函数得到的哈希表是一个映像. 冲突:如果两个关键字的哈希函数值相等,这种现象称为冲突. 处理冲突的几个方法: 1.开放地址法:用开放地址处理冲突就是当冲突发生时,形成一 ...
- 散列表 (Hash table,也叫哈希表)
散列表是根据关键字(Key value)而直接访问在内存存储位置的数据结构.也就是说,它通过把键值通过一个函数的计算,映射到表中一个位置来访问记录,这加快了查找速度.这个映射函数称做散列函数,存放记录 ...
- C#中哈希表与List的比较
简单概念 在c#中,List是顺序线性表(非链表),用一组地址连续的存储单元依次存储数据元素的线性结构. 哈希表也叫散列表,是一种通过把关键码值映射到表中一个位置来访问记录的数据结构.c#中的哈希表有 ...
- 哈希,哈希表,哈希Map
数组: 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二分查找时间复杂度小,为O(1):数组的特点是:寻址容易,插入和删除困难: 链表: 链表存储区间离散,占用内存比较宽松,故空间复杂 ...
- perl5 第九章 关联数组/哈希表
第九章 关联数组/哈希表 by flamephoenix 一.数组变量的限制二.定义三.访问关联数组的元素四.增加元素五.创建关联数组六.从数组变量复制到关联数组七.元素的增删八.列出数组的索引和值九 ...
随机推荐
- js中use或者using方法
看Vue.use方法,想起了以前工作中别人用过的use方法. var YANMethod = { using:function() { var a = arguments, o = this, i = ...
- angular2 学习笔记 (Typescript - Attribute & reflection & decorator)
更新 : 2018-11-27 { date: Date } 之前好像搞错了,这个是可以用 design:type 拿到的 { date: Date | null } 任何类型一但配上了 | 就 de ...
- 最短路径遍历所有的节点 Shortest Path Visiting All Nodes
2018-10-06 22:04:38 问题描述: 问题求解: 本题要求是求遍历所有节点的最短路径,由于本题中是没有要求一个节点只能访问一次的,也就是说可以访问一个节点多次,但是如果表征两次节点状态呢 ...
- Linux 各种软件的安装-tomcat8+JDK篇
其实自己没搞过php,主要还是弄java,tomcat和java是必不可少的 首先安装JDK,注意linux和winodws的jdk完全不同,别下载错了. 先 yum update 把软件更新一下 j ...
- js新打开页面
var a = document.createElement("a"); a.setAttribute("href", href); a.setAttribut ...
- Sereja and Two Sequences CodeForces - 425C (dp)
大意: 给定序列$a,b$, 每次可以任取两个相同大小的$a_i,b_j$删除$a_i,b_j$左侧所有元素, 花费为e, 得分1, 最后结束时必须再花费之前删除元素的个数, 不得分. 初始能量$s$ ...
- thinkphp或者kohana 导入和读取文件
1.无论是那个框架的导入,其实都是一样的原理的,但是首先我们要导入包,可能就这点不同. kohana的导入包的方法:require_once(Kohana::find_file('vendor','P ...
- virtualbox 中centOS在不能ssh
这个重要跟虚拟机的网络设置有关系.废话不多说. 针对一个网卡的形式.可以如下进行配置 1.网络-- 连接方式还选择“网络地址转换(NAT)” 其他不变,展开高级,设置端口转发 主机IP设为本机IP, ...
- maven中 install的install:install的区别
如果一个项目,你想安装jar包到本地仓库,可能会报The packaging for this project did not assign a file to the build artifact ...
- Vue keep-alive总结
<keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM. <keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是 ...