(十)哈希表

利用链表法解决冲突构建的一个hash表,最终的示意图如下图所示。

下面的代码实现的功能为:将一个网址进行hash,并存放于hash表中,利用hash表统计每个网址的访问次数。

链表节点包含三个元素:1)存放指向存放网址的指针。2)该网址出现的次数。3)指向下一个节点的指针。

/*******************************************
=================JJ日记=====================
作者: JJDiaries(阿呆) 
邮箱:JJDiaries@gmail.com
日期: 2013-11-13
============================================
哈希表:为实现快速查找而生。
实现一个散列表,并用链表法解决冲突。

应用实例:用一个hashTable记录网站中每个页面的访问量。
*******************************************/
/*================JJ日记=====================
作者: JJDiaries(阿呆) 
邮箱:JJDiaries@gmail.com
日期: 2013-11-13
============================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TABLELEN 1024 //hash表大小
#define SITELEN 256   //每个网址的最大长度
struct node{
	char *website;        //存放网址
	int counts;			  //存放该网址访问次数
	struct	node *next;   //指向下一个节点
};
static struct node *HashTable[TABLELEN]={NULL};

//将网址字符串转换成一个整数
unsigned long hash(char *key)
{
	unsigned long h=0;
	while(*key)
	{
		h=(h<<4)+*key++;
		unsigned long g=h&0Xf0000000L;
		if(g) h^=g>>24;
		  h&=~g;
	}
	return h%TABLELEN;
}
//将一个节点存入hash表
int insert(struct node *T[],char *website)
{
	if(website==NULL)
		return -1;
	int index=hash(website);
	//为空,说明此前没有此类记录,分配一个节点,用于存放新的网址,并将其链入hash表
	if(HashTable[index]==NULL){
		struct node *tmp=(struct node*)malloc(sizeof(struct node));
		if(tmp==NULL)
			return -1;
		tmp->website=(char*)malloc(strlen(website)+1);
		if(tmp->website==NULL)
			return -1;
		strncpy(tmp->website,website,strlen(website)+1);
		//将新分配的节点链到hash表的某一个槽的链表头部
		tmp->next=NULL;
		HashTable[index]=tmp;
		tmp->counts=1;
	}
	else{//index槽不为空,则需要比较该网址内容,判断其是否已经存在。
		struct node *tmp=HashTable[index];
		while(tmp!=NULL && strcmp(website,tmp->website)!=0)
			tmp=tmp->next;
		if(tmp)//说明website已经存在,将其counts加1
			tmp->counts++;
		else{
			tmp=(struct node*)malloc(sizeof(struct node));
			if(tmp==NULL)
				return -1;
			tmp->website=(char*)malloc(strlen(website)+1);
			if(tmp->website==NULL)
				return -1;
			strncpy(tmp->website,website,strlen(website)+1);
			//将新分配的节点链到hash表的某一个槽的链表头部
			tmp->next=HashTable[index]->next;
			HashTable[index]->next=tmp;
			tmp->counts=1;
		}
	}
	return 0;
}
//查看网址website是否有访问记录,如果有,则返回其访问次数,否则返回-1
int search(struct node *T[],char *website)
{
	int index=hash(website);
	//为空,说明此前没有此website记录
	if(HashTable[index]==NULL)
		return	-1;
	struct node *tmp=HashTable[index];
	while(tmp!=NULL && strcmp(website,tmp->website)!=0)
		tmp=tmp->next;
	if(tmp)//说明website已经存在,将其counts加1
		return	tmp->counts;
	return -1;
}
//free resources that allocated with malloc
void finit_table(struct node *T[])
{
	int i;
	struct node *tmp,*del;
	for(i=0;i<TABLELEN;++i){
		if(T[i]==NULL)
		  continue;
		tmp=T[i]->next;
		while(tmp!=NULL){
			del=tmp;
			tmp=tmp->next;
			free(del);
		}
		free(T[i]);
	}
}

int main()
{
	char * websites[]={"www.baidu.com",
				"www.google.com",
				"www.google.com",
				"www.bing.com",
				"www.google.com",
				"www.jjdiaries.com",
				"www.baidu.cn"};
	int i;
	for(i=0;i<7;++i)
		insert(HashTable,websites[i]);
	printf("www.google.com accessed times is :%d\n",search(HashTable,"www.google.com"));
	printf("www.baidu.com accessed times is :%d\n",search(HashTable,"www.baidu.com"));
	//note:free resource
	finit_table(HashTable);
}
/***************************************
viidiot@ubuntu:$ ./hash
www.google.com accessed times is :3
www.baidu.com accessed times is :1
***************************************/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值