Hash Table

散列用来以常数时间实现 Insert、Find 和 Delete 操作。

With [b]direct addressing[/b], an element with key k is stored in slot k.(相当于数组)
With [b]hashing[/b], this element is stored in slot h(k); that is, we use a hash function h to compute the slot from the key k.

h(k) 的范围远小于 k,所以必定会产生冲突(Collision)。
哈希函数表大小一般选择素数,可以使得均匀分布,缓解冲突。(为什么素数可以做到均匀分布?)

解决冲突方法一:链表数组实现,觉得代码很漂亮^_^
typedef int ElementType;
typedef struct ListNode *Position;

struct ListNode
{
ElementType Element;
Position Next;
};

typedef Position List;

struct HashTbl
{
int TableSize;
List *TheLists; // an array of lists
};

typedef struct HashTbl *HashTable;


HashTable InitializeTable(int TableSize)
{
HashTable H;
int i;

H = (HashTbl *)malloc(sizeof(struct HashTbl));
if (H == NULL)
Error("Out of space!!!");

H->TableSize = NextPrime(TableSize);

H->TheLists = (List *)malloc(sizeof(List) * H->TableSize);
if (H->TheLists == NULL)
Error("Out of space!!!");

/* Allocate list headers */
for (i = 0; i < H->TableSize; i++)
{
H->TheLists[i] = (ListNode *)malloc(sizeof(struct ListNode));
if (H->TheLists[i] == NULL)
Error("Out of space!!!");
else
H->TheLists[i]->Next = NULL;
}

return H;
}

int Hash(ElementType Key, int TableSize)
{
return Key%TableSize;
}

Position Find(ElementType Key, HashTable H)
{
List L = H->TheLists[Hash(Key, H->TableSize)];
Position P = L->Next;

while (P != NULL && P->Element != Key)
P = P->Next;

return P;
}

void Insert(ElementType Key, HashTable H)
{
Position Pos, NewCell;
List L;

Pos = Find(Key, H);

if (Pos == NULL)
{
NewCell = (ListNode *)malloc(sizeof(struct ListNode));
if (NewCell == NULL) {
Error("Out of space!!!");
} else {
L = H->TheLists[Hash(Key, H->TableSize)];
NewCell->Next = L->Next;
NewCell->Element = Key;
L->Next = NewCell;
}
}
}

void DestroyTable(HashTable H)
{
int i;

for (i = 0; i < H->TableSize; i++)
{
Position P = H->TheLists[i];
Position Tmp;

while (P != NULL) {
Tmp = P->Next;
free(P);
P = Tmp;
}
}

free(H->TheLists);
free(H);
}

解决冲突方法二:[b]Open addressing[/b],数组实现
每个位置需要附加一个属性,表示这个位置 [b]已存、空的或已删的[/b]。
1. 线性探测法:往后面一个一个地找。
2. 平方探测法:往后面跳着找。
只能懒惰删除,不能真删。即标记已删。
再散列:表的大小不够时,建立另外一个大约两倍大小的新表,扫描原表,一个一个的插入到新表中。

来自《数据结构与算法分析》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值