Hash表的概念及其代码实现


    1、哈希表概念
        1、让查找与数据规模无关,是常数级查找
        2、依据Key,精确匹配地址,找到这条记录。
        3、根据选取的Hash函数H(key)和处理冲突的方法,将一组记录(R1 R2……Rn)映象到记录的存储空间,所得到的记录表称为Hash表
    2、关于Hash表的讨论关键是两个问题
        1、构造(或选取)Hash函数的方法
            1、直接地址法
                 
            2、平方取中法
                
            3、叠加法
            4、保留除数法
                
            5、随机函数法
        2、确定解决冲突的方法
            1、冲突是指:表中某地址j中已存放有记录,而另一个记录的H(key)值也是j。
            2、处理冲突的方法:在地址j的前面或者后面找一空闲空间存放冲突的记录,或将相冲突的诸记录拉成链表等
            3、为减少冲突可引入一个装填因子a,a=n/m,
      其中m为表长,n为表中记录个数。
      一般a取0.7——0.8之间。
            4、开放地址法
                当发生冲突时,在H(key)的前后找一个空闲单元来存放冲突的记录,即在H(key)的基础上
获取下一地址:Hi=(H(key)+di)%m

            5、链地址法
                发生冲突时,将各冲突记录链在一起,即同义词的记录存于同一链表。
    3、算法思路
        1、对给定k,根据造表时选取的H(key)求H(k);
        2、若H(k)单元=^,则查找失败;
        3、否则k与该单元存放的key比较,若相等,则查找成功;
        4、若不等,则根据设定的处理冲突方法,找下一地址Hi,直到查找到或等于空为止。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define SIZE 100
#define PRIME 97

enum res
{
	ERROR = -5,
	NULLERROR,
	MALLOCREEOR,	
	HASHNULL,
	HASHERROR,
	OK
};

//定义数据域结构体类型
typedef int data_type;

//定义节点的结构体类型
typedef struct node
{
	data_type data;//数据域
	struct node *next;//指针域
}Node;

//定义hash表的结构体类型
typedef struct hash 
{
	Node *hash[SIZE];//指针数组,数组元素为链表地址
	int count;//记录个数
}Hash;

//菜单
void menu(void);

//创建hash函数
int HashFunc(data_type pData);

//创建hash表
Hash *createHash(void);

//创建一个新节点
Node *createNode(void);

//在hash表中添加数据
int insertItemHash(Hash *pHash,data_type pData);

//查找
int searchItemHash(Hash *pHash,data_type pData);

int main(void)
{
	Hash *pHash = NULL;
	pHash = createHash();
	data_type pData;
	int op = 0;
	int ret = 0;
	while(1)
	{
		menu();
		printf("请输入要操作的选项:\n");
		scanf("%d",&op);
		if(-1 == op)
		{
			break;
		}
		switch(op)
		{
			case 1://添加数据
				printf("请输入要添加的数据:\n");
				scanf("%d",&pData);
				ret = insertItemHash(pHash, pData);
				if(OK == ret)
				{
					printf("添加成功\n");
				}
				else
				{
					printf("添加失败\n");
				}
				break;
			case 2://查找数据
				printf("请输入要查找的数据:\n");
				scanf("%d",&pData);
				ret = searchItemHash(pHash, pData);
				if(ret == HashFunc(pData))
				{
					printf("该数据存放在Hash表中的第%d位\n",ret);
				}
				break;
			default:
				printf("输入有误!\n");
		}
	}
	return 0;
}

//菜单
void menu(void)
{
	printf("1................插入\n");
	printf("2................查找\n");
	printf("-1...............退出\n");
}

//创建hash函数
int HashFunc(data_type pData)
{
	return pData % PRIME; 
}

//创建hash表
Hash *createHash(void)
{
	Hash *pHash = NULL;
	pHash = (Hash *)malloc(sizeof(Hash));
	if(NULL == pHash)
	{
		perror("malloc hash error!");
		return NULL;
	}

	memset(pHash, 0, sizeof(Hash));

	return pHash;
}

//创建一个新结点
Node *createNode(void)
{
	Node *pNode = NULL;
	pNode = (Node *)malloc(sizeof(Node));
	if(NULL == pNode)
	{
		perror("malloc node error!");
		return NULL;
	}

	memset(pNode, 0, sizeof(Node));
	return pNode;
}

//在hash表中添加数据
int insertItemHash(Hash *pHash, data_type pData)
{
	if(pHash == NULL)
	{
		return HASHERROR;
	}
	int key = 0;
	Node *pTmp = NULL;
	Node *pNew = createNode();
	if(NULL == pNew)
	{
		return NULLERROR;
	}
	pNew -> data = pData;
	key = HashFunc(pData);
	pTmp = pHash -> hash[key];
	if(pTmp != NULL)
	{
		while(pTmp -> next != NULL)
		{
			pTmp = pTmp -> next;
		}
		pTmp -> next = pNew; 
	}
	else
	{
		pHash -> hash[key] = pNew;
	}
	pHash -> count ++;
	return OK;
}

//在hash表中查找数据
int searchItemHash(Hash *pHash, data_type pData)
{
	if(pHash == NULL)
	{
		printf("hash error");
		return HASHERROR;
	}
	if(0 == pHash -> count)
	{
		printf("hash null");
		return HASHNULL;
	}
	int key = 0;
	key = HashFunc(pData);
	Node *pTmp = pHash -> hash[key];
	while(1)
	{
		if(NULL == pTmp)
		{
			printf("找不到该数据");
			return ERROR;
		}
		if(pData == pTmp -> data)
		{
			break;
		}
		pTmp = pTmp -> next;
	}
	return key;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值