此哈希表中键和值的类型都是整数
1、哈希表实现的头文件hash.h:
头文件中定义了哈希表中哈希节点和哈希表结构体类型,以及此种哈希表的操作函数:
#ifndef __HASH_INC__
#define __HASH_INC__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HASH_SIZE 1093
/*
定义一个哈希表节点的结构体
成员变量:键,值,以及此节点的下一个节点的指针
*/
typedef struct _hashnode {
int key;
int value;
struct _hashnode * nextNode;
}HashNode;
/*
定义一个哈希表结构体
成员变量: 哈希表中节点总数,哈希节点指针数组
*/
typedef struct _hashtable{
int totalNodes;
HashNode ** pphashNodes;
}HashTable;
int createHashTable(HashTable ** pphashTable);
HashNode * getNodeHashTable(HashTable * pHashTable, int key);
int insertHashTable(HashTable * pHashTable, int key, int value);
int getValueHashTable(HashTable * pHashTable, int key, int * pValue);
int deleteKeyHashTable(HashTable * pHashTable, int key);
int deleteAllHashTable(HashTable ** ppHashTable);
#endif
2、此处哈希表实现的源文件hash.c:
每个函数的作用和使用方法在函数定义中详细说明:
#include "hash.h"
/*
创建一个哈希表,由* pphashTable返回,返回0表示创建成功,-1表示创建失败
*/
int createHashTable(HashTable ** pphashTable)
{
// 创建一个哈希表结构体
(* pphashTable) = (HashTable *)malloc(sizeof(HashTable));
if(NULL == (*pphashTable)){
return -1;
}
// 当前节点总数为0
// 分配一个大小为HASH_SIZE的节点指针数组,并初始化这些指针指向NULL
(*pphashTable)->totalNodes = 0;
(*pphashTable)->pphashNodes = (HashNode **)malloc(sizeof(HashNode *) * HASH_SIZE);
if (NULL == (*pphashTable)->pphashNodes){
return -1;
}
memset((*pphashTable)->pphashNodes, 0x00, sizeof(HASH_SIZE) * sizeof(HashNode *));
return 0;
}
// 用键,值向哈希表中插入
// 如果以key为键的节点已经存在,则改变对应的值。
// 计算节点指针索引
// 分配哈希节点,将传入的key和value写入对应的成员变量
// 如果由key计算出的节点指针索引的指针指向空,则将以上哈希节点的地址存入这个指针
// 如果指针索引的指针不为空,则从当前指向节点中nextNode寻找下一个节点,直接这个节点的nextNode指向空,
// 将新分配节点地址存入当前节点的nextNode。
int insertHashTable(HashTable * pHashTable, int key, int value)
{
int ikey = key % HASH_SIZE;
HashNode * tmpNode = NULL;
tmpNode = getNodeHashTable(pHashTable, key);
// tmpNode = (HashNode *)malloc(sizeof(HashNode));
if (tmpNode != NULL){
tmpNode->value = value;
return -1;
}
HashNode * newNode = (HashNode *)malloc(sizeof(HashNode));
if (NULL == newNode){
return -1;
}
newNode->key = key;
newNode->value = value;
newNode->nextNode = NULL;
if (pHashTable->pphashNodes[ikey] == NULL){
pHashTable->pphashNodes[ikey] = newNode;
}
else{
tmpNode = pHashTable->pphashNodes[ikey];
while (tmpNode->nextNode != NULL){
tmpNode = tmpNode->nextNode;
}
tmpNode->nextNode = newNode;
}
pHashTable->totalNodes++;
return 0;
}
/* 在哈希表中寻找以key为键的值,如果找到则用*pValue取回,并且函数返回0,否则函数返回-1 */
int getValueHashTable(HashTable * pHashTable, int key, int * pValue){
int ikey = key % HASH_SIZE;
HashNode * tmpNode;
if (pHashTable == NULL || pHashTable->totalNodes == 0 || pHashTable->pphashNodes[ikey] == NULL){
return -1;
}
tmpNode = pHashTable->pphashNodes[ikey];
while (tmpNode != NULL && tmpNode->key != key){
tmpNode = tmpNode->nextNode;
}
if (tmpNode == NULL){
return -1;
}
else{
* pValue = tmpNode->value;
return 0;
}
}
/*
在哈希表中寻找以key为键的哈希节点,如果找到,则返回这个节点,否则,返回NULL
*/
HashNode * getNodeHashTable(HashTable * pHashTable, int key)
{
int ikey = key % HASH_SIZE;
HashNode * tmpNode = NULL;
if (pHashTable == NULL || pHashTable->totalNodes == 0 || pHashTable->pphashNodes[ikey] == NULL){
return NULL;
}
tmpNode = pHashTable->pphashNodes[ikey];
while (tmpNode != NULL && tmpNode->key != key){
tmpNode = tmpNode->nextNode;
}
return tmpNode;
}
/* 在哈希表中,删除以key为键的哈希节点,如果删除成功返回0,否则返回-1 */
int deleteKeyHashTable(HashTable * pHashTable, int key)
{
int ikey = key % HASH_SIZE;
HashNode * tmpNode, * prevNode;
if (pHashTable == NULL || pHashTable->totalNodes == 0 || pHashTable->pphashNodes[ikey] == NULL){
return -1;
}
tmpNode = pHashTable->pphashNodes[ikey];
while (tmpNode && tmpNode->key != key){
prevNode = tmpNode;
tmpNode = tmpNode->nextNode;
}
if (tmpNode == NULL){
return -1;
}
else{
if (tmpNode == pHashTable->pphashNodes[ikey]){
pHashTable->pphashNodes[ikey] = tmpNode->nextNode;
}
else{
prevNode->nextNode = tmpNode->nextNode;
}
free(tmpNode);
pHashTable->totalNodes--;
return 0;
}
}
/* 释放哈希表中所有哈希节点以及哈希表 */
int deleteAllHashTable(HashTable ** ppHashTable)
{
int i;
HashNode * tmpNode, * nextNode;
if ((* ppHashTable) == NULL || (*ppHashTable)->totalNodes == 0)
{
return -1;
}
for (i = 0; i < HASH_SIZE; i++){
if ((*ppHashTable)->pphashNodes[i] == NULL){
continue;
}
else{
tmpNode = (*ppHashTable)->pphashNodes[i];
while (tmpNode->nextNode != NULL){
nextNode = tmpNode->nextNode;
free(tmpNode);
(*ppHashTable)->totalNodes--;
tmpNode = nextNode;
}
free(tmpNode);
(*ppHashTable)->totalNodes--;
(*ppHashTable)->pphashNodes[i] = NULL;
if ((*ppHashTable)->totalNodes == 0){
break;
}
}
}
free(* ppHashTable);
(*ppHashTable) = NULL;
return 0;
}
3、测试程序test.c如下:
#include <stdio.h>
#include "hash.h"
void test(int key1, int value1, int key2, int value2)
{
HashTable * pHashTable;
/* create hash table */
if (createHashTable(&pHashTable) != 0){
printf("create failed\n");
return;
}
/* insert key and value into hash table */
insertHashTable(pHashTable, key1, value1);
insertHashTable(pHashTable, key2, value2);
printf("current total nodes:%d\n", pHashTable->totalNodes);
/* get hashnode with key*/
HashNode * tmpNode = getNodeHashTable(pHashTable, key1);
printf("Get Hashnode with key:\n");
if (tmpNode != NULL){
printf("key:%d--->value:%d\n", key1, tmpNode->value);
}
else{
printf("key:%d-->no value in hash table\n",key1);
}
tmpNode = getNodeHashTable(pHashTable, key2);
if (tmpNode != NULL){
printf("key:%d--->value:%d\n", key2, tmpNode->value);
}
else{
printf("key:%d-->no value in hash table\n",key2);
}
/* get value with key*/
printf("Get value with key:\n");
int value = 0;
getValueHashTable(pHashTable, key1, &value);
printf("key:%d--->value:%d\n", key1, value);
getValueHashTable(pHashTable, key2, &value);
printf("key:%d--->value:%d\n", key2, value);
/* delete hashnode with key */
deleteKeyHashTable(pHashTable, key1);
printf("current totoal nodes:%d\n", pHashTable->totalNodes);
tmpNode = getNodeHashTable(pHashTable, key1);
if (tmpNode != NULL){
printf("key:%d--->value:%d\n", key1, tmpNode->value);
}
else{
printf("key:%d-->no value in hash table\n",key1);
}
tmpNode = getNodeHashTable(pHashTable, key2);
if (tmpNode != NULL){
printf("key:%d--->value:%d\n", key2, tmpNode->value);
}
else{
printf("key:%d-->no value in hash table\n",key2);
}
/* delete all hashnodes and hashtable */
deleteAllHashTable(&pHashTable);
}
int main()
{
test(1,11,2,22);
return 0;
}
4、用于编译的Makefile文件:
OBJS=$(patsubst %.c,%.o, $(wildcard ./*c))
TARGET=main
$(TARGET):$(OBJS)
$(CXX) $^ -o $(TARGET)
%.o:%.c
$(CXX) -c $^ -o $@
clean:
rm -rf *.o $(TARGET)
.PHONY:clean
5、执行make进行编译:
orangepi@orangepi5:~/C_program/hash_dir$ make
g++ -c hash.c -o hash.o
g++ -c test.c -o test.o
g++ hash.o test.o -o main
orangepi@orangepi5:~/C_program/hash_dir$ ls
hash.c hash.c.bak hash.h hash.o main Makefile test.c test.o
6、测试生成的可执行程序main:
orangepi@orangepi5:~/C_program/hash_dir$ ./main
current total nodes:2
Get Hashnode with key:
key:1--->value:11
key:2--->value:22
Get value with key:
key:1--->value:11
key:2--->value:22
current totoal nodes:1
key:1-->no value in hash table
key:2--->value:22