最简单的哈希表创建

        这个哈希表是根据  取余的规则进行划分每个桶子的索引 ,代码关键部分都写了注释 ,废话不多说,上代码.

      Hash.h代码如下:

#pragma once
#define MAXSIZE 128

//链表 节点的数据结构
typedef struct _LNode {

	int key;
	const void* value;
	_LNode* next;

}LNode;

typedef LNode* List;		//别名
typedef LNode* Element;		//别名,这俩是同一个,就是使用的时候用来区分一下

typedef struct _Hash {
	int m_typeLength;		// 哈希筒子的数量
	List* m_typeList;		// 指针数组
}Hash;

//初始化哈希
Hash* initHash(int length);


//删除节点
void deleteHash(Hash* hash, int key);

//插入节点
void insertHash(Hash* hash, int key, const void* value);

//销毁哈希
void destroyHash(Hash* hash);

//获取哈希表的索引值
int getHashIndex(Hash* hash, int key);

//获得当前节点的元素
const void* getValue(Element e);


//查找key的节点
Element findKey(int key,Hash* hash);

Hash.cpp代码如下:

#include "Hash.h"
#include <iostream>
using namespace std;

//初始化哈希
Hash* initHash(int length) {
	Hash* hash = NULL;
	hash = new Hash;
	
	//判断分配内存是否成功
	if (!hash) {
		cout << "哈希对象分配内存失败" << endl;
		return NULL;
	}

	//如果当前传过来的筒子数量是0或者比0小,那么就初始化为默认值
	if (length <= 0) {
		hash->m_typeLength = MAXSIZE;
	}
	else {
		hash->m_typeLength = length;
	}

	//给指针数组分配内存
	hash->m_typeList = new List[hash->m_typeLength];

	//判断指针数组是否分配内存成功
	if (!hash->m_typeList) {
		cout << "指针数组分配内存失败" << endl;
		delete hash;	//释放内存
		return NULL;
	}

//给每个桶子 的节点分配内存
	for (int i = 0; i < hash->m_typeLength; i++)
	{
		hash->m_typeList[i] = new LNode;
		if (!hash->m_typeList[i]) {
			cout << "筒子里的节点分配内存失败" << endl;
			delete[] hash->m_typeList;        //分配失败就要手动释放已经分配的内存
			delete hash;            
			return NULL;
		}
		else {
			memset(hash->m_typeList[i], 0, sizeof(LNode));	//把每个桶子里的节点都置为0
		}

	}
	return hash;
}


//删除节点
void deleteHash(Hash* hash,int key) {
	List L = NULL;
	Element cur = NULL, pre = NULL;

	L = hash->m_typeList[getHashIndex(hash, key)];
	cur = L->next;				//获取第一个有效节点,因为头节点是空的,所以需要next
	pre = L;
	while (cur != NULL && cur->key != key)
	{
		pre = cur;		//记录上一次的节点,方便把链表重新连接起来
		cur = cur->next;
	}
	if (cur) {
		pre->next = cur->next;		//重新连接链表
		delete cur;
	}
}

//插入节点
void insertHash(Hash* hash, int key, const void* value) {
	List L = NULL;
	Element e = NULL, tmp = NULL;

	//插入节点需要判断key值,不能有两个相同的key
	e = findKey(key, hash);

	//如果不存在
	if (e == NULL) {
		
		tmp = new LNode;

		if (!tmp) {
			cout << "插入的节点 内存分配失败" << endl;
			return;
		}

		L = hash->m_typeList[getHashIndex(hash, key)];	//获得桶子的头节点
		
		//头插法
		tmp->next = L->next;
		tmp->key = key;
		tmp->value = value;
		L->next = tmp;

	}
	else {
		cout << "该key 已经存在了" << endl;
	}
	return;
}

//销毁哈希
void destroyHash(Hash* hash) {
	List L = NULL;
	Element e = NULL,tmp = NULL;
	
	//遍历每一个桶子的节点,然后挨个销毁
	for (int i = 0; i < hash->m_typeLength; ++i) {
		L = hash->m_typeList[i];        //挨个获得每个桶子的头节点
		e = L->next;                    //获得第一个有效节点
		while (e != NULL)
		{
			tmp = e;
			e = e->next;
			delete tmp;
		}
		delete L;        //销毁头节点
	}
	
	delete[] hash->m_typeList;        //销毁指针数组
	delete hash;

}

//获取哈希表的索引值
int getHashIndex(Hash* hash, int key) {
	
	return key % hash->m_typeLength;

}

//获得当前节点的元素
const void* getValue(Element e) {
	return e ? e->value : NULL;
	
}


//查找key的节点
Element findKey(int key, Hash* hash) {
	List L = NULL;
	Element e = NULL;
	
	L = hash->m_typeList[getHashIndex(hash, key)];        //获得key值在哈希表中的位置
	e = L->next;                                //所有的桶子的头节点都是空,所以需要next
	while (e != NULL && e->key != key)
	{
		e = e->next;
	}
	return e;
}

main.cpp 代码如下:

#include "Hash.h"
#include <iostream>
using namespace std;
int main()
{
	Hash* hash;
	const char* arr[] = { "张一","张二","张三","张四","张五" };

	//初始化
	hash = initHash(7);

	//插入五个节点
	for (int i = 0; i < 5; ++i) {
		insertHash(hash, i+1, arr[i]);
	}
	
	//输出所有的内容
	for (int i = 0; i < hash->m_typeLength; ++i) {
		Element e = findKey(i, hash);
		if(e)
		cout << "key: " << i + 1 << " 的数据为: " << (const char*)getValue(e) << endl;
		else {
			cout << "没有找到" << i+1 << "的节点" << endl;
		}
	}
	cout << endl;
	//删除key值为3的节点
	deleteHash(hash, 3);

	//再次输出所有的内容
	for (int i = 0; i < hash->m_typeLength; ++i) {
		Element e = findKey(i, hash);
		if (e)
			cout << "key: " << i + 1 << " 的数据为: " << (const char*)getValue(e) << endl;
		else {
			cout << "没有找到" << i + 1 << "的节点" << endl;
		}
	}

	//销毁哈希函数
	destroyHash(hash);
}

猜你喜欢

转载自blog.csdn.net/weixin_45428525/article/details/121570699