哈希表—开散列

基本概念

开散列—首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中。 (负载因子a不超过0.5;如果超出必须考虑增容 )
在这里插入图片描述

具体实现

定义

#define MAX_SIZE 10
typedef int HBDdtaType;
typedef struct HashBuckNode  //结点
{
	struct HashBuckNode* _next;
	HBDdtaType _data;
}HashBuckNode, *pHashBuckNode;
typedef struct HashBuck  //哈希表
{
	pHashBuckNode _Hasharr;
	int _size;  //元素个数
	int _capacity;  //最大元素个数
}HashBuck, *pHashBuck;

初始化

void HashInit(pHashBuck phashbuck, int capacity)
{
	assert(phashbuck);
	//开辟空间
	//在申请内存大小时,不能直接将指针类型放到sizeof内部
	pHashBuckNode ph = (pHashBuckNode)malloc(capacity * sizeof(HashBuckNode));
	if (NULL == ph)
	{
		assert(0);
	}
	//赋初始值
	for (int i = 0; i < capacity; i++)
	{
		(ph + i)->_data = i;
		(ph + i)->_next = NULL;
	}
	phashbuck->_Hasharr = ph;
	phashbuck->_size = 0;
	phashbuck->_capacity = capacity;
}

哈希函数

int HashFun(HBDdtaType data, int capacity)
{
	return data % capacity;
}

创建新结点

pHashBuckNode HBByNode(HBDdtaType data)
{
	pHashBuckNode newnode = (pHashBuckNode)malloc(sizeof(HashBuckNode));
	if (NULL == newnode)
	{
		assert(0);
	}
	newnode->_data = data;
	newnode->_next = NULL;
	return newnode;
}

判空

int HashEmpty(pHashBuck phashbuck)
{
	assert(phashbuck);
	return phashbuck->_size == 0;
}

元素个数

int HashSize(pHashBuck phashbuck) 
{
	assert(phashbuck);
	return phashbuck->_size;
}

插入

扩容
void Dilatation(pHashBuck phashbuck)
{
	//开辟新空间,为原空间的两倍
	int capacity = phashbuck->_capacity * 2;
	pHashBuckNode ph = (pHashBuckNode)malloc(capacity * sizeof(HashBuckNode));
	if (NULL == ph)
	{
		assert(0);
	}
	//新空间的状态为空
	for (int i = 0; i < capacity; i++)
	{
		(ph + i)->_data = i;
		(ph + i)->_next = NULL;
	}
	//拷贝元素
	for (int i = 0; i < phashbuck->_capacity; i++)
	{
		
		if (((phashbuck->_Hasharr) + i)->_next)//存在元素
		{
			pHashBuckNode cur = ((phashbuck->_Hasharr) + i)->_next;  //原空间
			while (cur)
			{
				//拿出元素
				int data = cur->_data;
				//计算桶号
				int address = HashFun(data, capacity);//新空间的桶号
				//头插入到新空间
				pHashBuckNode newnode = HBByNode(data);
				if (NULL == (ph + address)->_next)
				{
					(ph + address)->_next = newnode;
				}
				else
				{
					newnode->_next = (ph + address)->_next;
					(ph + address)->_next = newnode;
				}
				//头删旧空间
				((phashbuck->_Hasharr) + i)->_next = cur->_next;
				free(cur);
				cur = NULL;
				cur = ((phashbuck->_Hasharr) + i)->_next;
			}
		}
	}
	//释放旧空间
	free(phashbuck->_Hasharr);
	phashbuck->_Hasharr = ph;
	phashbuck->_capacity = capacity;
}
插入
void HashInsert(pHashBuck phashbuck, HBDdtaType data)
{
	assert(phashbuck);
	//扩容
	if (phashbuck->_size == phashbuck->_capacity)
		Dilatation(phashbuck);
	//计算桶号
	int address = HashFun(data, phashbuck->_capacity);
	//查看元素是否存在
	//遍历桶号所在的链表,查看元素是否存在
	pHashBuckNode cur = ((phashbuck->_Hasharr) + address)->_next;  //从第一个元素开始
	while (cur)
	{
		if (cur->_data == data)
		{
			return;
		}
		cur = cur->_next;
	}
	//不存在
	//创建结点,开辟空间
	pHashBuckNode newnode = HBByNode(data);
	//头插入链表
	//第一个结点
	if (NULL == ((phashbuck->_Hasharr) + address)->_next)
	{
		((phashbuck->_Hasharr) + address)->_next = newnode;
	}
	else
	{
		newnode->_next = ((phashbuck->_Hasharr) + address)->_next;
		((phashbuck->_Hasharr) + address)->_next = newnode;
	}
	phashbuck->_size++;
}

删除

int HashDelete(pHashBuck phashbuck, HBDdtaType data)
{
	assert(phashbuck);
	//计算桶号
	int address = HashFun(data, phashbuck->_capacity);
	pHashBuckNode cur = ((phashbuck->_Hasharr) + address)->_next;  //从第一个元素开始
	pHashBuckNode pre = ((phashbuck->_Hasharr) + address);
	while (cur)
	{
		if (cur->_data == data)
		{
			pre->_next = cur->_next;
			free(cur);
			cur = NULL;
			phashbuck->_size--;
			return 1;
		}
		pre = cur;
		cur = cur->_next;
	}
	return 0;
}

查找

int HashFind(pHashBuck phashbuck, HBDdtaType data)
{
	assert(phashbuck);
	//计算桶号
	int address = HashFun(data, phashbuck->_capacity);
	pHashBuckNode cur = ((phashbuck->_Hasharr) + address)->_next;  
	while (cur)
	{
		if (cur->_data == data)
		{
			return address;
		}
		cur = cur->_next;
	}
	return 0;
}

销毁

void HashDestroy(pHashBuck phashbuck)
{
	assert(phashbuck);
	//释放每个结点
	for (int i = 0; i < phashbuck->_capacity; i++)
	{

		if (((phashbuck->_Hasharr) + i)->_next)//存在元素
		{
			pHashBuckNode cur = ((phashbuck->_Hasharr) + i)->_next;
			while (cur)
			{
				//头删结点
				((phashbuck->_Hasharr) + i)->_next = cur->_next;
				free(cur);
				cur = NULL;
				cur = ((phashbuck->_Hasharr) + i)->_next;
			}
		}
	}
	//释放旧空间
	free(phashbuck->_Hasharr);
	phashbuck->_Hasharr = NULL;
	phashbuck->_capacity = 0;
	phashbuck->_size = 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值