hash 表 插入数据自动排序 简单实现

1,首先定义节点 

一个hash表里面存了10 个链表节点 基于这个原理 读者可以实现更为复杂的hash表 要想更复杂 就可以定义一个新的结构体 里面含有多个hash表指针 层层套娃 下面是一个表中10个链表节点的实现 


struct MyNode
{
	int date;
	MyNode* pNext;
};

struct HashTable
{
	MyNode* val[10];  // 10个链表节点
};

2,数据存放

我们可以自己定义一个规则将数据 按照这个规则将数据存放在相应的链表中 我们叫这个规则称为hash函数 下面例子是 将要存放的数据%10 也就是根据其各位数将其存放在对应的链表下标中 而且 对存进来的数据进行有序存放 (从小到大) 

//创建哈希表
//参数:无
//返回值:hash表头指针
HashTable* creatHashTable(){
	HashTable* phash = new HashTable;
	memset(phash, 0, sizeof(HashTable)); // 整个表里面的10个链表地址初始化为0
	return phash;


// 插入数据放链表里面
bool insertHashTable(HashTable* phash, int date){
	if (phash == NULL){
		return false;
	}
	// 准备新节点获取存储地址
	MyNode* pNode = phash->val[date % 10];
	if (pNode == NULL){
		phash->val[date % 10] = new MyNode;
		phash->val[date % 10]->date = date;
		phash->val[date % 10]->pNext = NULL;
	}
	else{
		if (date <= pNode->date){
			// 前插
			MyNode* newNode = new MyNode;
			newNode->date = date;
			newNode->pNext = pNode;
			pNode = newNode;
		}
		else  // 遍历存放
		{
			while (pNode->pNext!=NULL && pNode->pNext->date<date) // 当下一个节点的数据小于要插入的数据时 移动节点指针
			{
				pNode = pNode->pNext;
			}
			if (pNode->pNext == NULL){
				// 后插入
				pNode->pNext = new MyNode;
				pNode->pNext->date = date;
				pNode->pNext->pNext = NULL;
			}
			else{
				// 夹逼插入
				MyNode* newNode = new MyNode;
				newNode->date = date;
				newNode->pNext = pNode->pNext;
				pNode->pNext = newNode;
			}
		}
	}
	return true;
}

我们函数返回值可以自己设置 

3,查找数据节点

根据数据查找返回数据所在的节点

// 根据数据查找节点
MyNode* findDate(HashTable* phash, int findDate){
	if (phash == NULL){
		return NULL;
	}
	MyNode* pNode = phash->val[findDate % 10];
	if (pNode == NULL){
		return NULL;
	}
	while (pNode)
	{
		if (pNode->date == findDate){
			return pNode;
		}
		pNode = pNode->pNext;
	}
	// 否则没有找到
	return NULL;
}

4,删除数据

       我们可以将要删除是数据传进我们写的查找函数 再根据查找的节点来删除 注意:要想删除目标节点 就要知道目标节点的前一个节点 而目标节点的前一个节点又需要 重新从头节点开始遍历

// 删除数据
bool delFindDate(HashTable* phash,int delDate){

	// 使用查找函数 直接找到要删除节点的 指针/ 地址
	MyNode* pNode = findDate(phash, delDate);
	if (pNode == NULL){
		return false; // 找不到 删除失败
	}
	// 要想删除这个节点 那么要知道它的上一个节点 用上一个节点指向 它 的下一个节点 然后把 它 删除
	// 要想知道 它 的上一个节点 必须从头节点找过来
	MyNode* tempNode = phash->val[delDate % 10];
	 
	while (tempNode->pNext!=pNode)
	{
		tempNode = tempNode->pNext;
	}// 跳出循环则找到它的上一个节点了
	tempNode->pNext = pNode->pNext;
	delete pNode;
	return true;
}

5,删除整个hash表

// 删除整个表
void clearHashTable(HashTable* &phash){
	if (phash == NULL){
		return;
	}
	MyNode* phead;
	MyNode* pNode;
	for (int i = 0; i < 10; i++){
		// 查表
		if ((phead = phash->val[i]) != NULL)
		{
			// 如果链表不为空 那么 遍历链表
			while (phead)
			{
				pNode = phead;
				phead = phead->pNext;
				delete pNode;
			}
		}
	}// 最后删除装这10个链表头节点 的容器

	delete[]phash;
	phash = NULL;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值