数据结构算法之哈希表

哈希表也称作散列表,是介于链表和二叉树之间的一种结构体。因为这二者之间各有优缺点,链表的插入和删除操作可以在O(1)内实现,很方便,但是查询操作很麻烦,二叉树的数据排序严格有序,但是需要建立在大量的指针的基础之上,所以,而为了综合他们的长处,一种新的数据结构就诞生出来了–哈希表。
就如同一个网站管理系统,整个互联网有许许多多的网页,有的网页是关于新闻方面的,有的网页是视频网站,有的网页是提供图片的,如果需要快速的查询一个《微微一笑很倾城》这个电视剧,那么不可能将互联网中的所有网站都遍历过一遍,那样效率太慢了。所以,会将《微微一笑很倾城》电视剧放到以视频为归类的网站上,将奥巴马访华的新闻事件存放到新闻专页,将梵高画像放到图片网站上。然后查询《微微一笑很倾城》的时候就可以直接定位到视频网站,再从视频网站上查找具体电视节目。哈希表的大体思路就如上所述。
下面就是哈希表的简单操作代码:
哈希表的结构:
#define Elemtype int
#define TABLESIZE 10
typedef struct _Node
{
Elemtype data;
struct _Node* next;
}Node;
typedef struct _HashTable
{
Node* array[TABLESIZE];
}HashTable;

创建哈希表:
HashTable* CreateHashTable()
{
HashTable* p;
p = (HashTable*)malloc(sizeof(HashTable));
memset(p, 0, sizeof(HashTable));
return p;
}

查找哈希表:
Node* SearchHashTable(HashTable *H, Elemtype data)
{
Node* pn;
if(NULL == H)//表未创建,返回空
{
return NULL;
}
if(NULL == (pn = H->array[data%TABLESIZE]))//对应位置没有元素,返回空
{
return NULL;
}
while(pn)//遍历键值下的链表
{
if(data == pn->data);//若找到,返回节点
{
return pn;
}
pn = pn->next;
}
return NULL;//键值下没有匹配节点,返回空
}

插入节点:
bool InsertHashNode(HashTable* H, Elemtype data)
{
Node *pn;
if(NULL == H)
{
return NULL;
}
if(NULL == H->array[data%TABLESIZE])//键值下链表为空,则创建
{
pn = (Node*)malloc(sizeof(Node));
memset(pn, 0, sizeof(Node));
pn->data = data;
H->array[data%TABLESIZE] = pn;
return TRUE;
}
if(NULL != SearchHashTable(H, data))//若已经存在,则返回
return NULL;
pn = H->array[data%TABLESIZE];//定位到键值链
while(pn->next)
{
pn = pn->next;
}
pn->next = (Node *)malloc(sizeof(Node));
memset(pn->next, 0, sizeof(Node));
pn->next->data = data;
return TRUE;
}

删除节点:
bool DeleteHashNode(HashTable *H, Elemtype data)
{
if(NULL == H)
{
return NULL;
}
Node *pn;
if(NULL == (pn = HashTable[data%TABLESIZE]))
{
return NULL;
}
Node *prev = pn;//用来记录当前节点的前一个节点
while(pn)
{
if(data == pn->data)
{
prev = pn->next;//前一个节点指向当前节点的下一个节点
free(pn);//将当前节点删除
return TRUE;
}
prev = pn;
pn = pn->next;
}
return NULL;//没有找到对应的节点
}

以上内容仅作参考,如有错误,欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值