关于哈希表

代码不是很正确,有的函数还没有测试!!!
//哈希表
#include
#include <stdio.h>
using namespace std;

#define HASHMAXSIZE 11
typedef int KeyType;
typedef int ValType;
typedef size_t (*HashFunc)(KeyType key); //函数指针,控制元素存入位置
//size_t (*HashFunc)(KeyType key);

//哈希元素
typedef struct HashElem
{
KeyType key;
ValType val;
struct HashElem *next;
}HashElem;

//哈希表
typedef struct HashTable
{
HashElem* data[HASHMAXSIZE]; //散列表 HASHMAXSIZE 表的长度
HashFunc func; //控制元素存储在散列表中的位置
int size; //散列表中元素的个数
}HashTable;

//初始化函数
size_t HashFuncDefault(KeyType key)
{
return key%HASHMAXSIZE; //取余数
}
void HashInit(HashTable* ht,HashFunc func)
{
if (NULL == ht)
{
return;
}
ht->size = 0;
ht->func = func;
for (int i = 0; i < HASHMAXSIZE; i++)
{
ht->data[i] = NULL;
}
return;
}

//销毁
void ElemDestory(HashElem* node)
{
if (node != NULL)
{
delete node;
node = NULL;
}

//free(node);
return;

}
void HashDestory(HashTable* ht)
{
if (NULL == ht)
{
return;
}
ht->size = 0;
ht->func = NULL;
for (int i = 0; i < HASHMAXSIZE; i++)
{
HashElem* cur = ht->data[i];
while (cur != NULL)
{
HashElem* nextnode = cur->next;
ElemDestory(cur);
printf(“销毁节点:%d\n”,i);
cur = nextnode;
}
}
return;
}
//打印函数 打印不为空的链表
void HashPrint(HashTable* ht,const char* msg)
{
printf("%s\n",msg);
if (NULL == ht)
{
return;
}
for (int i = 0; i < HASHMAXSIZE; i++)
{
if (NULL == ht->data[i])
{
continue; //如果为空,就继续寻找
}
printf(“HashElem=%d\t”,i);
HashElem* cur = ht->data[i];
while (cur != NULL)
{
printf("[%d:%d]\t",cur->key,cur->val);
cur = cur->next;
}
printf("\n");
}
return;
}
//创建链表节点
HashElem* ElemCreate(KeyType key,ValType val)
{
HashElem* new_node = new HashElem;
new_node->key = key;
new_node->val = val;
new_node->next = NULL;
return new_node;
}
//插入操作
HashElem* HashBucketFind(HashElem* head,KeyType key) //查找链表中是否存在当前要插入的元素
{
HashElem* cur = head;
while (cur != NULL)
{
if (key == cur->key)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
void HashInsert(HashTable* ht,KeyType key,ValType val)
{
if (NULL == ht)
{
return;
}
//1、根据key值,计算插入位置offset
size_t offset = ht->func(key);
//2、在offset对应链表查找要插入的key
HashElem* ret = HashBucketFind(ht->data[offset],key);
//3、若key存在,插入失败
if (ret != NULL)
{
return;
}
//4、若key不存在,可进行插入操作(头插)
HashElem* new_node = ElemCreate(key,val);
new_node->next = ht->data[offset];
ht->data[offset] = new_node;
//5、插入结束
ht->size++;
return;
}
//查找操作 给定一个key,查找对应的val
int HashFind(HashTable* ht,KeyType key,ValType val)
{
if (NULL == ht || NULL == val)
{
return 0;
}
if (ht->size == 0) //哈希表为空
{
return 0;
}
//1、根据key计算offset
size_t offset = ht->func(key);
//2、在offset对应的链表中遍历查找当前要查找的元素
HashElem* ret = HashBucketFind(ht->data[offset],key);
if (NULL == ret)
{
return 0;
}
val = ret->val;
return 1;
}
//删除操作 给定一个key,删除对应的元素
//查找要删除元素以及其父节点
int HashBucketFindEx(HashElem* head,KeyType to_find,HashElem** pre,HashElem** to_delete)
{
if (NULL == head || NULL == pre || NULL == to_delete)
{
return 0;
}
HashElem* ret = head;
HashElem* ex = NULL;
for (; ret != NULL; ret = ret->next)
{
if (ret->key == to_find)
{
break;
}
}
if (NULL == ret)
{
return 0;
}
pre = ex;
to_delete = ret;
return 1;
}
void HashRemove(HashTable
ht,KeyType key)
{
if (NULL == ht)
{
return;
}
if (ht->size == 0)
{
return;
}
//1、根据key计算offset
size_t offset = ht->func(key);
//2、在offset对应链表查找要删除的元素
HashElem
pre;
HashElem* to_remove;
int ret = HashBucketFindEx(ht->data[offset],key,&pre,&to_remove);
//3、没有找到要删除的元素
if (ret == 0)
{
return;
}
//4、要删除元素为链表元素节点
if (NULL == pre)
{
ht->data[offset] = to_remove->next;
}
//5、要删除元素为链表中一个节点
else
{
pre->next = to_remove->next;
}
ElemDestory(to_remove);
//6、删除操作后–size
ht->size–;
return;
}
int main()
{
HashTable *ht=new HashTable;
//函数指针的用法
HashFunc func= HashFuncDefault;

HashInit(ht,func);

HashInsert(ht, 47, 1);
HashInsert(ht, 7,  2);
HashInsert(ht, 29, 3);
HashInsert(ht, 11, 4);
HashInsert(ht, 16, 5);
HashInsert(ht, 92, 6);
HashInsert(ht, 22, 7);
HashInsert(ht, 8, 8);
HashInsert(ht, 3, 9);

HashPrint(ht,"哈希表");

//printf("销毁整个哈希表\n");
//HashDestory(ht);
//HashPrint(ht, "哈希表");

system("pause");
return 0;

}
/*关于函数指针
1、原来有一个函数int max(int x,inty){return x<y?x:y;}
2、定义函数指针 int (*func)(int x,int y);
3、将函数赋值给指针 func=max;
4、之后直接调用这个指针即可
int ret=(*func)(3,5);
ret=5;
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值