基于线性探测法的散列表

来源:互联网 发布:淘宝索尼丽驰专卖店 编辑:程序博客网 时间:2024/05/21 14:08
#include <stdio.h>//基于线性探测法的散列表//使用线性探测解决键冲突问题,核心思想就是利用数组空位,当使用//哈希函数计算出数组索引后,开始检测该索引位置是否已经被使用,如//果已经使用,则索引向后递增(如果超出数组索引,则需要进行回绕到//数组起始索引),直到找到空位为止,或者数组空间已全部被使用,无//法再扩冲,由于这里利用的是数组空间,所以通常情况下,需要该数组//支持动态调整数组空间功能,当前简化了这步流程,仅使用静态数组进//行分析。#define TEST_CASE  (1)#define MAX_HASH_ENTRY  5typedef struct{    int used;    int key;    int val;} HASH_ENTRY;HASH_ENTRY hashTableEntrys[MAX_HASH_ENTRY] = {0};int g_hashTableEntryCount = 0;//正整数类型的KEY的散列函数//通常采用除留余法,这里通过对KEY进行求余,使得KEY分布在hashTable//的数组中,同时为了减少键冲突,除数通常选择为素数,比如当前示例//选择为97int hashFunctionForInt(int key){    // M 通常为素数    //hashKey = key % M    int hashKey = key % 97;     return hashKey;}//计算哈希表数组的索引// 1首先算出hashKey// 2 之后根据当前哈希表数组长度进行求余操作,避免计算出来的hashKey大于//  数组长度,导致出现溢出int hashIndex(int key){    int hashKey = hashFunctionForInt(key);    return hashKey % MAX_HASH_ENTRY;}//新增条目//1 当前不支持动态调整数组空间,所以需要检测溢出的隐患//2 进行数组空位查找void put(int key, int val){    int index = hashIndex(key);    if ( g_hashTableEntryCount >= MAX_HASH_ENTRY )    {        printf("don't put, array full.\r\n");        return;     }    while ( hashTableEntrys[index].used )    {        index = (index + 1) % MAX_HASH_ENTRY;    }    hashTableEntrys[index].used = 1;    hashTableEntrys[index].key = key;    hashTableEntrys[index].val = val;    g_hashTableEntryCount++;}//查找//这里有3种情况会退出循环//1 没有对应的空位了,即没有找到需要的数组//2 有对应的空位,但键值不是要查找的//3 防止数组出现满的情况,这时候需要进行环绕检测,避免死循环int get(int key){    int val = -1;    int index = hashIndex(key);    int curGetIndex = index;    while ( hashTableEntrys[index].used )    {        if ( curGetIndex == index )        {            break;         }        if ( hashTableEntrys[index].key == key  )        {            val = hashTableEntrys[index].val;            break;         }        index = (index + 1) % MAX_HASH_ENTRY;    }    return val;}//删除//线性探测法由于在进行查找时,遇到空位则停止,所以在进行删除//时,后面数据的问题,比如当前要删除hashKey = 3,当删除第一个//条目时,第一个位置出现了空洞,此时需要将后面项全部删除并重//新插入,否则后面数据将无法访问。// -------------------------// |3|3|3|3| | | | | | | | |// -------------------------int delete(int key){    int find = 0;    int index = hashIndex(key);    while ( hashTableEntrys[index].used )    {        if ( hashTableEntrys[index].key == key )        {            find = 1;            break;         }        index = (index + 1) % MAX_HASH_ENTRY;    }    if ( find )    {        int curDeleteIndex = index;        hashTableEntrys[index].used = 0;        g_hashTableEntryCount--;        index = (index + 1) % MAX_HASH_ENTRY;        while ( hashTableEntrys[index].used && (curDeleteIndex != index) )        {            put(hashTableEntrys[index].key, hashTableEntrys[index].val);            hashTableEntrys[index].used = 0;            g_hashTableEntryCount--;            index = (index + 1) % MAX_HASH_ENTRY;        }    }    return find ? 0 : -1 ;}void testCase0(){    put(1, 1);    put(2, 2);    put(3, 3);    put(4, 4);    put(5, 5);    put(6, 6);    put(7, 7);    printf("find key %d, val %d\r\n", 3, get(3));    printf("find key %d, val %d\r\n", 7, get(7));}void testCase1(){    put(3, 3);    put(3, 3);    put(3, 3);    put(3, 3);    put(3, 3);    put(3, 3);    put(3, 3);    delete(3);    delete(3);    delete(3);    delete(3);    delete(3);    delete(3);    delete(3);    printf("find key %d, val %d\r\n", 3, get(3));}int main(){    printf("max hashTable entry %d\r\n", MAX_HASH_ENTRY);    switch ( TEST_CASE )    {        case 0: testCase0(); break;        case 1: testCase1(); break;        default: break;    }    return 0;}

0 0
原创粉丝点击