hash链表法范例(转)

Hash
设某元素的关键字为key,用函数Hash(key)的值作为该元素的地址,所构造的查找表称为哈希表(或散列表),函数Hash(key)称为哈希(Hash)函数(或散列函数)。
若两个关键字k1 != k2,但H(k1) = H(k2)。这种现象称为冲突,k1和k2称为同义词。
要避免冲突,需要构造一个恰当的哈希函数。常见的构造哈希函数的方法有:直接定址法、除留余数法、平方取中法等。
有时冲突是不能完全避免的,须妥善处理。
处理冲突的方法:链地址法(拉链法)、开放定址法
链地址法(拉链法)
将所有发生冲突的元素存储在一个链表中,并将这些链表的表头指针存放在一个表中。所构造的散列表称为开散列表。
插入操作的最坏情况运行时间为O(1),查找操作的最坏情况运行时间与表的长度成正比。

ChainedHashMain.c
#include <stdio.h>
#include <stdlib.h>
#include "hash.h"

/**//*简单操作示例*/
int main(int argc, char **argv)
...{
    CHashTable t;
    CHashNode *p;
    int a[N] = ...{47, 7, 29, 11, 16, 92, 22, 8, 3, 0, 37, 89, 4, 21};

    ChainedHashCreate(&t, a);
    printf("[+] hash table create ok. ");

    p = ChainedHashSearch(&t, 92);
    PrintNodeKey(p);

    ChainedHashInsert(&t, 92);

    ChainedHashDelete(&t, 92);
    p = ChainedHashSearch(&t, 92);
    PrintNodeKey(p);

    return 1;
}


hash.h
#ifndef _HASH_H
#define _HASH_H

#define M 11
#define N 14
#define DELETE -1

typedef int KeyType;
typedef struct Node...{
    KeyType key;
    struct Node *next;
}CHashNode;
typedef CHashNode *CHashTable[M];

int Hash(KeyType k);
int ChainedHashInsert(CHashTable *t, KeyType k);
int ChainedHashCreate(CHashTable *t, int *a);
int ChainedHashDelete(CHashTable *t, KeyType k);
CHashNode *ChainedHashSearch(CHashTable *t, KeyType k);
void PrintNodeKey(CHashNode *ph);

#endif

hash.c
#include <stdio.h>
#include <stdlib.h>
#include "hash.h"

int Hash(KeyType k)
...{
    return k % M;
}

/**//*
*根据a[0..N-1]中结点建立散列表t[0..M-1]
*/
int ChainedHashCreate(CHashTable *t, int *a)
...{
    int i;

    for(i = 0; i < M; i++)
        (*t)[i] = NULL;
    for(i = 0; i < N; i++)
        ChainedHashInsert(&(*t), a[i]);

    return 1;
}

/**//*
*将关键字k插入散列表t中
*/
int ChainedHashInsert(CHashTable *t, KeyType k)
...{
    CHashNode *p;
    int addr;

    p = ChainedHashSearch(&(*t), k);
    if(p)
    ...{
        printf("Duplicate Key! ");

        return 0;
    }
    else
    ...{
        addr = Hash(k);
        p = (CHashNode *)malloc(sizeof(CHashNode));
        p->key = k;
        p->next = (*t)[addr];
        (*t)[addr] = p;

        return 1;
    }
}

/**//*
*在散列表t中查找关键字k
*/
CHashNode *ChainedHashSearch(CHashTable *t, KeyType k)
...{
    CHashNode *p;
    int addr;

    addr = Hash(k);
    p = (*t)[addr];
    if(p == NULL)
    ...{
        return NULL;
    }
    else
    ...{
        while(p && p->key != k)
            p = p->next;

        return p;
    }
}

/**//*
*在散列表t中删除关键字k
*/
int ChainedHashDelete(CHashTable *t, KeyType k)
...{
    CHashNode *p, *q;
    int addr;

    addr = Hash(k);
    p = (*t)[addr];
    if((p == NULL) || (p->key == DELETE))
    ...{
        printf("No such key! ");
        return 0;
    }
    else
    ...{
        q = p;
        while(p && p->key != k)
        ...{
            q = p;
            p = p->next;
        }
        if(q != p)
            q->next = p->next;
        else
            p->key = DELETE;

        return 1;
    }
}

void PrintNodeKey(CHashNode *p)
...{
    if(p == NULL)
        printf("It's a NULL node! ");
    else
        printf("%d ", p->key);
}
posted @ 2011-05-24 02:33  elwin  阅读(1263)  评论(0)    收藏  举报