您的位置:首页 > 理论基础 > 数据结构算法

数据结构——杂凑表(拉链法)

2008-01-24 14:02 316 查看
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
= ...{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);


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: