算法学习 - HashTable开放地址法解决哈希冲突

来源:互联网 发布:物业管理系统源码免费 编辑:程序博客网 时间:2024/06/11 23:26

开放地址法解决哈希冲突

线性开放地址法

线性开放地址法就是在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 intstruct 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文件。

0 0
原创粉丝点击