本博文源于浙江大学《数据结构》,散列表是数据结构的后续内容,对前面的基本功要求明显。而散列表最多的只不过是查找而已。用了散列只要解决地址冲突,就可以O(1)查找,下面给出散列表(开放定址法)用平方探测法解决冲突的操作。
散列的理论(小白必会):
散列表基本常识(必知必会·理论篇)
测试用例
HashTable Tb = CreateTable(13);//创建哈希表
int flag = Insert(Tb,47);//往哈希表插入值
int Pos = Find(Tb,47);//寻找哈希表的位置
printf("data's position:%d\n",Pos);
int data = Tb->Cells[Pos].Data;
printf("data:%d\n",data);
flag = Insert(Tb,47);//插入一个已经有的值47
源码附上
//类型名称:符号表(SymbolTable)
//数据对象集:符号表是"名字(Name)-属性(Attribute)"对的集合
//操作集:对一个具体的符号表Table∈SymbolTable,
//一个给定名字Name∈NameType,属性Attr∈Attribute,以及正整数TableSize,
//符号表的基本操作主要有
// SymbolTable CreateTable(int TableSize);
//创建空的符号表,其最大长度为TableSize
// AttributeType Find(SymbolTable Table,NameType Name);
//获取符号表Table中指定名字Name对应的属性
// bool Insert(SymbolTable Table,NameType Name,Attribute Attr);
//向Table中插入一个新名字Name及其属性Attr。成功返回true,
//若Name已存在则返回false
//开放地址法
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#define MAXtABLESIZE 100000
typedef int ElementType;
typedef int Index;
typedef Index Position;
typedef enum {Legitimate,Empty,Deleted } EntryType;
typedef struct HashEntry Cell;
struct HashEntry {
ElementType Data;//存放元素
EntryType Info;
};
typedef struct TblNode *HashTable;//散列表类型
struct TblNode {
int TableSize; // 表的最大长度
Cell *Cells; //存放散列单元数据的数组
};
int NextPrime(int N)
{
int i,p=(N%2)?N+2:N+1;
while(p<=MAXtABLESIZE) {
for(i=(int)sqrt(p);i>2;i--)
if(!(p%i)) break;
if(i==2) break;
else p+=2;
}
return p;
}
HashTable CreateTable(int TableSize) {
HashTable H;
int i;
H = (HashTable)malloc(sizeof(struct TblNode));
H->TableSize = NextPrime(TableSize);
H->Cells = (Cell *)malloc(H->TableSize * sizeof(Cell));
for(i=0;i<H->TableSize;i++)
H->Cells[i].Info = Empty;
return H;
}
int Hash(const int Key,int TableSize)
{
unsigned int H = 0;
int Temp = Key;
H = (H<<5)+ Temp++;
return H%TableSize;
}
Position Find(HashTable H,ElementType Key)
{
Position CurrentPos, NewPos;
int CNum = 0;
NewPos = CurrentPos = Hash(Key,H->TableSize);
while(H->Cells[NewPos].Info != Empty && H->Cells[NewPos].Data!=Key) {
if(++CNum%2) {
NewPos = CurrentPos + (CNum+1)*(CNum+1)/4;
if(NewPos >= H->TableSize)
NewPos = NewPos % H->TableSize;
}else {
NewPos = CurrentPos - CNum * CNum * CNum /4;
while(NewPos<0)
NewPos += H->TableSize;
}
}
return NewPos;
}
bool Insert(HashTable H,ElementType Key) {
Position Pos = Find(H,Key);
if(H->Cells[Pos].Info != Legitimate) {
H->Cells[Pos].Info = Legitimate;
H->Cells[Pos].Data = Key;
return true;
}else {
printf("failed");
return false;
}
}
int main()
{
HashTable Tb = CreateTable(13);//创建哈希表
int flag = Insert(Tb,47);//往哈希表插入值
int Pos = Find(Tb,47);//寻找哈希表的位置
printf("data's position:%d\n",Pos);
int data = Tb->Cells[Pos].Data;
printf("data:%d\n",data);
flag = Insert(Tb,47);//插入一个已经有的值47
return 0;
}