开放定址法解决hash冲突问题(C语言实现)

/*
 * hashquad.c 开放定址法解决hash冲突问题
 */

#include
#include

#include "hashquad.h"
#include "fatal.h"

#define MIN_TABLE_SIZE (10)
#define REHASH_FACTOR    (0.7)

enum kind_of_entry { legitimate, empty, deleted };

struct hash_entry
{
    element_type    element;
    enum kind_of_entry    info;
};

typedef struct hash_entry cell;

struct hash_tbl
{
    int table_size;        /* 表容量 */
    int entry_cnt;        /* 已填入的单元数量 */
    cell    *cells;
};

static int
need_rehash( hash_table h )
{
    return ( h->entry_cnt > h->table_size * REHASH_FACTOR );
}

static int
next_prime( int N )
{
    int i;

    if ( N % 2 ==  0 )
        N++;

    for ( ; ; N += 2 ){
        for ( i = 3; i * i <= N; i += 2 ){
            if ( N % i == 0 )
                goto cont_outer;
        }
        return N;
cont_outer:    ;
    }
}

static Index
hash( element_type key, int table_size )
{
    return key % table_size;
}

static hash_table
initialize_table( int table_size )
{
    hash_table h;
    int i;

    if ( table_size < MIN_TABLE_SIZE )
        Error("Table size too small!");

    h = malloc( sizeof( struct hash_tbl ) );
    if ( h == NULL )
        Error("Out of space!");

    h->table_size = next_prime( table_size );

    h->cells = malloc( sizeof( cell ) * h->table_size );
    if ( h->cells == NULL ){
        free( h );
        Error("Out of space!");
    }

    for ( i = 0; i < h->table_size; i++){
        h->cells[ i ].info = empty;
    }
    h->entry_cnt = 0;

    return h;
}

static Pos
find( element_type key, hash_table h )
{
    Pos    cur_pos;
    int    collision_num;

    collision_num = 0;
    cur_pos = hash( key, h->table_size );

    /*
    当hash表大部分被占满,这个过程可能很慢。
    也有可能进入死循环! 需要在适当的时候进行rehash!
    */
    while ( h->cells[ cur_pos ].info != empty
        &&  h->cells[ cur_pos ].element != key ){
        cur_pos += 2 * ++collision_num - 1;
        if ( cur_pos >= h->table_size )
            cur_pos -= h->table_size;
    }

    return cur_pos;
}

static void
insert( element_type key, hash_table h )
{
    Pos    p;

    p = find( key, h );
    if ( h->cells[ p ].info != legitimate ){
        h->cells[ p ].info = legitimate;
        h->cells[ p ].element = key;
        h->entry_cnt++;
    }
}

static hash_table
rehash( hash_table h)
{
    int i, old_size;
    cell *old_cells;

    old_cells = h->cells;
    old_size = h->table_size;

    /* 创建一个新的double size的空表 */
    h = initialize_table( 2 * old_size );

    /* 拷贝旧表的数据到新表 */
    for ( i = 0; i < old_size; i++ ){
        if ( old_cells[ i ].info == legitimate )
            insert( old_cells[ i ].element, h );
    }

    free( old_cells );

    return h;
}

/************    The next is test functions    ***************/
#define get_array_size(array)    ( sizeof(array) / sizeof(array[0]) )


void
test_hashquad( void )
{
    int i;
    Pos    p;
    hash_table h;
    element_type datas[100];

    for ( i = 0; i < get_array_size( datas ); i++ ){
        datas[i] = rand() % 1000;
    }

    h = initialize_table( 13 );
    if ( h == NULL )
        Error("Initialize error!");

    for ( i = 0; i < get_array_size( datas ); i++ ){
        insert( datas[i], h );
        /* 在每次插入操作后检查是否需要rehash */
        if ( need_rehash( h ) )
            h = rehash( h );
    }

    p = find( 67, h );
    if ( h->cells[p].info != legitimate ){
        printf("\n\t key value 67 not in hash table!\n");
    }else{
        printf("\n\t key value 67 in hash table!\n");    
    }

    p = find( datas[31], h );
    if ( h->cells[p].info != legitimate ){
        printf("\n\t key value %d not in hash table!\n",datas[31]);
    }else{
        printf("\n\t key value %d in hash table!\n",datas[31]);
    }

    i = i;
    return;
}

/*********************************************************************************************************/
/* hashquad.h */

#ifndef _HASHQUAD_H_
#define _HASHQUAD_H_

typedef int    element_type;
typedef unsigned int Index;
typedef Index    Pos;

struct hash_tbl;
typedef struct hash_tbl *hash_table;

#endif
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(1359) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值