哈希表的实现(c语言)

实现哈希表的方法有两种方法:开放寻址法 、链地址法

  • 开放寻址法:在开放寻址法中,所有的元素都存储在哈希表的数组中,冲突发生时会探测下一个可用的位置,直到找到一个空闲的位置。这种方法保持了元素的顺序,但可能导致聚集(clustering)。

  • 链地址法:链地址法使用一个数组来存储指向链表头部的指针,每个链表存储具有相同哈希值的元素。如果发生冲突,新的元素将被添加到该链表的末尾。这种方法可以避免聚集,但不保持元素的顺序。

链地址法:
cpp 复制代码
#include <stdio.h>
#include  <stdlib.h>

#define SIZE 20
typedef struct Node {
	int value;
	int key;
	struct Node* next;
}Node;

typedef struct{
	Node *table[SIZE];
}HashTable; 

//初始化哈希表
void initHashTable(HashTable *ht){
	for (int i = 0; i < SIZE; i++) {
        ht->table[i] = NULL;
    }
} 

int getKey(int value){
	return value%SIZE;
}

//向哈希表中插入数据  hash公式就是 value%20 
void addvalue(int value,HashTable *ht){
	Node *node=(Node*)malloc(sizeof(Node));
	node->value=value;
	int key=getKey(value);
	node->key=key;
	node->next=NULL;
	Node *tmp=ht->table[key];
	if(tmp!=NULL){
		while(tmp->next){
			tmp=tmp->next;	
		}
		tmp->next=node;
	}else{
		ht->table[key]=node; 
	} 
}

//查看哈希表中是否包含此值 
int containValue(int value,HashTable *ht){
	int key=getKey(value);
	if(key<0){
		printf("查询非法数据!");
		return -1;
	}
	Node* tmp=ht->table[key];
	if(tmp==NULL) return 0;
	while(tmp){
		if(tmp->value==value) return 1;
		tmp=tmp->next;
	}
	return 0;
}

// 释放哈希表内存
void freeHashTable(HashTable *ht) {
    for (int i = 0; i < SIZE; i++) {
        Node *current = ht->table[i];
        while (current != NULL) {
            Node *temp = current;
            current = current->next;
            free(temp);
        }
    }
}


int main(){
	HashTable table;
	initHashTable(&table);
	addvalue(1,&table);
	addvalue(3,&table);
	addvalue(6,&table);
	addvalue(7,&table);
	addvalue(11,&table);
	addvalue(23,&table);
	addvalue(21,&table);
	addvalue(27,&table);
	addvalue(87,&table);
	
	printf("%d\n",containValue(-1,&table));
	freeHashTable(&table);
	system("pause");
	return 0;
}
开放寻址法
cpp 复制代码
#include <stdio.h>
#include  <stdlib.h>

#define SIZE 100

typedef struct Node {
	int value;
	int key;
	struct Node* next;
}Node;

typedef struct {
	Node* node[SIZE];
	int magnification;
}HashTable;

void initHashTable(HashTable *ht){
	int i;
	for(i=0;i<SIZE;i++){
		ht->node[i]=NULL;
	}
	ht->magnification=1;
}

//获取索引,-2:该元素已经无法插入,-1:非法值 
int getKey(int value,HashTable *ht){
	int key=value%SIZE;
	if(key>=0&&ht->node[key]!=NULL){
		int i;
		for(i=key+1;i<SIZE;i++){
			if(ht->node[i]==NULL) return i;
		}
		return -2;
	}else if(ht->node[key]==NULL){
		return key;
	}
	return -1;
}

void pushToHt(int value,HashTable *ht){
	int key=getKey(value,ht);
	if(key==-1){
		printf("非法值的查找!\n");
	}else if(key==-2){
		printf("%d插入失败!\n",value);
	}else{
		Node *node=(Node*)malloc(sizeof(Node));
		node->key=key;
		node->value=value;
		node->next=NULL;
		ht->node[key]=node;
	} 
}

int containValue(int value,HashTable *ht){
	int key=value%SIZE;
	if(key==-1){
		printf("查询非法数据!\n");
		return -1;
	}else{
		return ht->node[key]!=NULL&&ht->node[key]->value==value?1:0;
	}
}

int main(){
	HashTable ht;
	initHashTable(&ht);
	pushToHt(1,&ht);
	pushToHt(2,&ht);
	pushToHt(23,&ht);
	pushToHt(11,&ht);
	pushToHt(12,&ht);
	pushToHt(14,&ht);
	pushToHt(5,&ht);
	pushToHt(15,&ht);
	pushToHt(31,&ht);
	printf("%d\n",containValue(14,&ht));
	system("pause");
	return 0;
}
相关推荐
wuqingshun3141591 分钟前
蓝桥杯 11. 打印大X
数据结构·算法·职场和发展·蓝桥杯·深度优先
wuqingshun3141591 小时前
蓝桥杯 2. 确定字符串是否是另一个的排列
数据结构·c++·算法·职场和发展·蓝桥杯
长沙火山2 小时前
9.ArkUI List的介绍和使用
数据结构·windows·list
AAAA劝导tx3 小时前
List--链表
数据结构·c++·笔记·链表·list
格格Code3 小时前
八大排序——冒泡排序/归并排序
数据结构·算法·排序算法
fantasy_44 小时前
LeetCode238☞除自身以外数组的乘积
java·数据结构·python·算法·leetcode
努力创造奇迹4 小时前
C 语言联合体、枚举、typedef 详解
c语言·开发语言
ImAlex4 小时前
C语言结构体中0字节数组(柔性数组)的妙用(附内存排布图解和完整代码)
c语言
纪元A梦4 小时前
华为OD机试真题——阿里巴巴找黄金宝箱Ⅰ(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
java·c语言·javascript·c++·python·华为od·go
ImAlex5 小时前
如何使用gcc的-finstrument-functions特性通过打印函数调用栈辅助理解复杂C/C++项目的函数调用关系
linux·c语言