哈希表的实现(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;
}
相关推荐
XuanRanDev30 分钟前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
代码猪猪傻瓜coding32 分钟前
力扣1 两数之和
数据结构·算法·leetcode
EricWang13581 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
我是谁??1 小时前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
南宫生2 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
希言JY2 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
午言若2 小时前
C语言比较两个字符串是否相同
c语言
weixin_432702263 小时前
代码随想录算法训练营第五十五天|图论理论基础
数据结构·python·算法·深度优先·图论
passer__jw7673 小时前
【LeetCode】【算法】283. 移动零
数据结构·算法·leetcode
TeYiToKu4 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm