散列表实现(平方探测法)

来源:互联网 发布:淘宝营销工具 编辑:程序博客网 时间:2024/06/05 23:06

from 《数据结构与算法分析》

开放地址散列法中,如果有冲突发生,就尝试选择另外单元,直到找出空的单元为止。

更一般的,单元h0(X) ,h1(X),h2(X)等等

hi(X)=(Hash(X)+F(i)) mod TableSize  且 F(0)=0

对开放地址散列表算法来说,装填因子应低于0.5

平方探测法是消除线性探测中的一次聚集问题的冲突解决方法。流行的选择是F(i)=i*i;

定理:如果使用平方探测,且表的大小是素数,那么当表至少有一半是空的时候,总能够插入一个新的元素。

// HashTable_OpenAddressingHash.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <stdlib.h>#define MinTableSize 5typedef unsigned int Index;typedef Index Position;typedef int ElementType;struct HashTbl;typedef struct HashTbl* HashTable;enum KindOfEntry{Legitimate,Empty,Deleted};struct HashEntry{ElementType Element;enum KindOfEntry Info;};typedef struct HashEntry Cell;struct HashTbl{int TableSize;Cell* TheCells;};static int NextPrime(int TableSize);static bool IsPrime(int num);static int Fmod(int a, int b, int c);HashTable InitTable(int TableSize);void error(char* str);int Hash(ElementType Key, int TableSize);bool Insert(ElementType Key, HashTable H);bool Delete(ElementType Key, HashTable H);HashTable Rehash(HashTable H);void Release(HashTable H);void error(char* str){printf("%s\n", str);exit(0);}HashTable InitTable(int TableSize){HashTable H;int i;if (TableSize < MinTableSize)error("TableSize is too small");H = (HashTable)malloc(sizeof(HashTbl));if (H == NULL)error("Out Of Memory");H->TableSize = NextPrime(TableSize);H->TheCells = (Cell*)malloc(sizeof(struct HashEntry)*sizeof(H->TableSize));if (H->TheCells == NULL)error("Out Of Memory");for (i = 0; i < H->TableSize; i++)H->TheCells[i].Info = Empty;return H;}Position Find(ElementType Key, HashTable H){Position CurPos=Hash(Key,H->TableSize);int CollisionNum=0;while (H->TheCells[CurPos].Info != Empty&&H->TheCells[CurPos].Element != Key){CurPos += 2 * (++CollisionNum) - 1;//如果新的定位越过数组,那么可以通过减去TableSize把它拉回数组范围内if (CurPos >= H->TableSize)CurPos -= H->TableSize;}return CurPos;}int Hash(ElementType Key, int TableSize){return Key%TableSize;}bool Insert(ElementType Key, HashTable H){Position Pos;Pos = Find(Key, H);if (H->TheCells[Pos].Info != Legitimate){H->TheCells[Pos].Info = Legitimate;H->TheCells[Pos].Element = Key;return true;}return false;}bool Delete(ElementType Key, HashTable H){Position P = Find(Key, H);//懒惰删除 if (H->TheCells[P].Info == Legitimate&&H->TheCells[P].Element == Key){H->TheCells[P].Info == Empty;return true;}return false;}HashTable Rehash(HashTable H){int i = 0;int OldSize = H->TableSize;Cell* OldCells = H->TheCells;H = InitTable(2 * OldSize);for (i = 0; i < OldSize; i++){if (OldCells[i].Info == Legitimate){Insert(OldCells[i].Element, H);}}free(OldCells);return H;}void Release(HashTable H){free(H->TheCells);free(H);}static int Fmod(int a, int b, int c)//快速模取幂  {if (b == 1) return a;int t = Fmod(a, b / 2, c);t = (t * t) % c;if (b & 1) t = (t * a) % c;return t;}static bool IsPrime(int num)//米勒-拉宾算法  {for (int i = 0; i < 100; ++i){if (Fmod(rand() % (num - 1) + 1, num - 1, num) != 1)//a的取值为[1,num-1],a的值需要变化,所以用到随机函数  return false;}return true;} static int NextPrime(int TableSize){while (!IsPrime(TableSize)){TableSize++;}return TableSize;}


原创粉丝点击