哈希表概念和实现,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 一.数组变量的限制二.定义三.访问关联数组的元素四.增加元素五.创建关联数组六.从数组变量复制到关联数组七.元素的增删八.列出数组的索引和值九 ...
随机推荐
- maven配置环境变量失败解决办法
配置maven路径什么的统统正确,最后测hi不成功.在网上搜索了好多资料方法都解不了 具体问题具体对待吧,如果有和我类似的小伙伴,可以尝试一下我的这个办法,在maven路径后面加/bin path变量 ...
- JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分
Dao层是使用了Hibernate连接数据库.操作数据库(增删改查).Service层:引用对应的Dao数据库操作,在这里可以编写自己需要的代码(比如简单的判断).Action层:引用对应的Servi ...
- spring cloud: Hystrix(二):简单使用@HystrixCommand的commandProperties配置@HistrixProperty隔离策略
spring cloud: Hystrix(二):简单使用@HystrixCommand的commandProperties配置@HistrixProperty隔离策略 某电子商务网站在一个黑色星期五 ...
- Aliyun cdn访问日志下载
1.日志下载代码(cdn.py)(请在Linux系统下运行) #!/usr/bin/python2.7 # -*- coding:utf-8 -*- import sys,os,gzip,json,r ...
- python基础之面向对象的多继承以及MRO算法
内容梗概: 1. python多继承 2. python经典类的MRO 3. python新式类的MRO C3算法 1.python多继承 class Shen: def fly(self): pri ...
- World Tour CodeForces - 667D (bfs最短路)
大意: 有向图, 求找4个不同的点ABCD, 使得d(A,B)+d(D,C)+d(C,A)最大
- SWUST OJ(954)
单链表的链接 #include <stdio.h> #include <stdlib.h> typedef struct LinkNode //单链表节点结构的定义 { cha ...
- php-fpm.conf文件的位置在哪里
在php的安装目录下的etc目录下:
- DFS CCPC2017 南宁I题
The designers have come up with a new simple game called “Rake It In”. Two players, Alice and Bob, i ...
- html和jsp的区别及优缺点
♥ HTML(Hypertext Markup Language)文本标记语言,它是静态页面,和JavaScript一样解释性语言,为什么说是解释性语言呢?因为,只要你有一个浏览器那么它就可以正常显示 ...