开放地址法解决哈希冲突
线性开放地址法
线性开放地址法就是在hash之后,当发现在位置上已经存在了一个变量之后,放到它下一个位置,假如下一个位置也冲突,则继续向下,依次类推,直到找到没有变量的位置,放进去。
平方开放地址法
平方地址法就是在hash之后,当正确位置上存在冲突,不放到挨着的下一个位置,而是放到第2^0位置,假如继续冲突放到2^1的位置,依次2^3... 直到遇到不冲突的位置放进去。
双散列开放地址法
双散列同上,不过不是放到2^的位置,而是放到key - hash(key, tablesize)的位置,假如继续冲突,则放到2 (key - hash(key,tablesize))的位置。
代码如下:
// // HashTable.h // HashTable_OpenAddress // // Created by Alps on 14-8-6. // Copyright (c) 2014年 chen. All rights reserved. // #ifndef HashTable_OpenAddress_HashTable_h #define HashTable_OpenAddress_HashTable_h #define ElementType int struct HashEntry; typedef HashEntry* entry; typedef unsigned int Index; typedef Index Position; struct HashTb; typedef HashTb* HashTable; HashTable InitializeHashTable(int TableSize); Position Find(ElementType X, HashTable H); void Insert(ElementType X, HashTable H); HashTable ReHash(HashTable H); enum KindOfEntry{empty ,full}; struct HashEntry{ ElementType element; KindOfEntry info; }; typedef entry Cell; struct HashTb{ int TableSize; Cell TheCells; }; #endif
上面这个代码是:HashTable.h文件。
// // main.cpp // HashTable_OpenAddress // // Created by Alps on 14-8-6. // Copyright (c) 2014年 chen. All rights reserved. // #include <iostream> #include "HashTable.h" #include <math.h> #define MinTableSize 1 //hash函数 int Hash(ElementType key, int TableSize){ return key%TableSize; } //判断是否是素数 bool Prime(int num){ for (int i = 2; i <= sqrt(num); i++) { if (num % i == 0) { return false; } } return true; } //找到比tablesize大的最小的素数 int NextPrime(int TableSize){ if (TableSize <= 2) { return 2; }else{ while (!Prime(TableSize)) { TableSize++; } } return TableSize; } //找到比tablesize小的最大的素数 int PrePrime(int TableSize){ if (TableSize <= 2) { return 2; }else{ TableSize--; while (!Prime(TableSize) && TableSize > 2) { TableSize--; } } return TableSize; } //初始化散列表 HashTable InitializeHashTable(int TableSize){ if (TableSize < MinTableSize) { //error("it's too small"); exit(0); } HashTable H = (HashTable)malloc(sizeof(HashTb)); H->TableSize = NextPrime(TableSize); H->TheCells = (Cell)malloc(sizeof(struct HashEntry) * H->TableSize); for (int i = 0; i < H->TableSize; i++) { H->TheCells[i].info = empty; } return H; } //线性开放地址法查找 Position LineFind(ElementType key, HashTable H){ int i = Hash(key, H->TableSize); while (H->TheCells[i].info != empty && H->TheCells[i].element != key) { i += 1; if (i >= H->TableSize) { i = i % H->TableSize; } } return i; } //平方开放地址法查找 Position SquareFind(ElementType key, HashTable H){ int i = Hash(key, H->TableSize); int num = 0; while (H->TheCells[i].info != empty && H->TheCells[i].element != key) { i -= num*num; ++num; i += num*num; if (i >= H->TableSize) { i = i % H->TableSize; } } return i; } //双散列查找 Position DoubleHashFind(ElementType key, HashTable H){ int i = Hash(key, H->TableSize); int num = PrePrime(H->TableSize); num =num - key%num; while (H->TheCells[i].info != empty && H->TheCells[i].element != key) { i += num; if (i >= H->TableSize) { i = i % H->TableSize; } } return i; } //查找函数 Position Find(ElementType key, HashTable H){ // return LineFind(key, H); // return SquareFind(key, H); return DoubleHashFind(key, H); } //线性开发地址法 void LineInsert(ElementType key, HashTable H){ Position P = LineFind(key, H); if (H->TheCells[P].info != full) { H->TheCells[P].element = key; H->TheCells[P].info = full; } } //平方开放地址法 void SquareInsert(ElementType key, HashTable H){ Position P = SquareFind(key, H); if (H->TheCells[P].info != full) { H->TheCells[P].element = key; H->TheCells[P].info = full; } } //双散列开放地址法 void DoubleHashInsert(ElementType key, HashTable H){ Position P = DoubleHashFind(key, H); if (H->TheCells[P].info != full) { H->TheCells[P].element = key; H->TheCells[P].info = full; } } //插入函数 void Insert(ElementType key, HashTable H){ // LineInsert(key, H); // SquareInsert(key, H); DoubleHashInsert(key, H); } //主函数 int main(int argc, const char * argv[]) { HashTable H = InitializeHashTable(10); Insert(5, H); // printf("%d\n",H->TableSize); Position P = Find(5, H); printf("%d\n",H->TheCells[P].element); printf("%d\n",P); ///////////////////////////////////// Insert(16, H); // printf("%d\n",H->TableSize); P = Find(16, H); printf("%d\n",H->TheCells[P].element); printf("%d\n",P); ///////////////////////////////////// Insert(27, H); // printf("%d\n",H->TableSize); P = Find(27, H); printf("%d\n",H->TheCells[P].element); printf("%d\n",P); return 0; }
这是main.cpp文件。
算法学习 - HashTable开放地址法解决哈希冲突,布布扣,bubuko.com
时间: 2024-10-09 20:58:57