C语言实现哈希表(开放地址法)

笔者最近学习数据结构中的哈希表,并用C语言简单实现了。
此博客旨在交流心得。

这篇博客介绍的是开放地址法构造的哈希表

哈希表原理可以参考这篇文章:哈希表原理介绍

如果要参考拉链法构造的哈希表,请参考这篇文章:C语言实现哈希表(拉链法)

结构体说明

typedef struct element
{
	int key;		// key值  唯一不重复 
	int data;		// data 域  
}Element;

其中data域可以改为自定义的结构体(当然后续 main函数 部分代码需要做相应修改)
key 值经由哈希函数的计算会得到一个映射的地址

typedef struct table
{
	Element **elm;	//  
	int count;		// 记录表中记录的数据个数 
	int size;	// 哈希表的大小 = SIZE = 50
}Table;

注意:elm 为一个指向 Element结构体的指针数组 的指针(请好好理解),即创建了一个 Element 类型的指针数组,而 elm 指向这个数组的头地址 故声明为二级指针(指向指针的指针) 。

部分函数说明:
创建哈希表函数:

Table * init_Table()
{
	Table *t = (Table*)malloc(sizeof(Table));
	t->size = REMAINDER;
	t->count = 0;
	t->elm = (Element **)malloc(SIZE*sizeof(Element*));
	/*
	创建一个长度为13的指针数组,类型为Element*
	并将数组头地址赋值给 elm 的二级指针 
	*/ 
	int i;
	for(i=0 ; i<t->size ; i++)
	{
		t->elm[i] = NULL;	// 将数组的每个域赋空 
	}	
	return t;
}

声明 Table 类型的变量,为其开辟空间,并返回其地址。

在初始化时,对指针类型的变量要注意初始化(有的编译器会帮你赋空,有的则不会)

插入函数

void Insert(Table *t,Element * k)		//将key值插入到哈希表中 
{
	int i;
	int position;
	position = hash(k->key);
	
	for(i=1 ; t->elm[position]!=NULL && i<t->size ;i++ )
	{
		position=(hash(position)+i)%t->size;
	}
	t->elm[position] = k;	
	t->count += 1;
	return ;
}

开放地址法的一般形式为:
其中 H(key)是哈希函数,m为表的长度
此种方法容易造成堆积。解决方法是改进哈希函数或用使用拉链法(各有优劣)。

查找函数:

int serch(Table *t, Element * k)		//查找 value 并返回其所在的地址 
{
	int position=hash(k->key);
	while(t->elm[position]->key != k->key)
	{
		position = hash(position+1);
		if(t->elm[position]==NULL || position == hash(k->key))
		/*
		出现以下几种情况即判断查找失败
		1.对应的 position 位置的地址为空 
		2.遍历整个表都没有对应的 key 值 
		*/ 
		return -1;
	}
	
	return position;	
}

出现以下几种情况即判断查找失败
1.对应的 position 位置的地址为空
2.遍历整个表都没有对应的 key 值

完整代码:

#include<stdio.h>
#include<stdlib.h>
#define REMAINDER 13
#define SIZE 50 

typedef struct element
{
	int key;		// key值  唯一不重复 
	int data;		// data 域  
}Element;

typedef struct table
{
	Element **elm;	//  
	int count;		// 记录表中记录的数据个数 
	int size;	// 哈希表的大小 = SIZE = 50
}Table;

int hash(int key)
{
	return key%REMAINDER;	
}

Table * init_Table()
{
	Table *t = (Table*)malloc(sizeof(Table));
	t->size = SIZE;
	t->count = 0;
	t->elm = (Element **)malloc(SIZE*sizeof(Element*));
	/*
	创建一个长度为13的指针数组,类型为Element* 
	并将数组头地址赋值给 elm 的二级指针 
	*/ 
	int i;
	for(i=0 ; i<t->size ; i++)
	{
		t->elm[i] = NULL;	// 将数组的每个域赋空 
	}	
	return t;
}

void Insert(Table *t,Element * k)		//将key值插入到哈希表中 
{
	int i=0;
	int position;
	position = hash(k->key);
	
	for(i=1 ; t->elm[position]!=NULL && i<t->size ;i++ )
	{
		position=(hash(position)+i)%t->size;
	}
	t->elm[position] = k;	
	t->count += 1;
	return ;
}

int serch(Table *t, Element * k)		//查找 value 并返回其所在的地址 
{
	int position=hash(k->key);
	while(t->elm[position]->key != k->key)
	{
		position = hash(position+1);
		if(t->elm[position]==NULL || position == hash(k->key))
		/*
		出现以下几种情况即判断查找失败
		1.对应的 position 位置的地址为空 
		2.遍历整个表都没有对应的 key 值 
		*/ 
		return -1;
	}
	
	return position;	
}


void Print_Table(Table *t)		//打印部分哈希表 
{
	int i;
	for(i=0 ; i<13 ; i++)
	{
		if(t->elm[i])
		printf("[%d %d] ",t->elm[i]->key , t->elm[i]->data);
		else printf("NULL ");
	}	
	printf("\n");
}

int main()
{
	Table *t = init_Table();
	
	Element a[]={{12,99},{13,98},{26,87},{14,77},{15,100},{10,59}};
	int length = sizeof(a)/sizeof(Element);
	
	int i;
	for(i=0 ; i<length ; i++)
	{
		Insert(t,&a[i]);
	}
	Print_Table(t);
	printf("a[3] is locat %d\n",serch(t,&a[3]));
	free(t);
}


运行截图:
在这里插入图片描述

谢谢观看~

发布了7 篇原创文章 · 获赞 12 · 访问量 774

猜你喜欢

转载自blog.csdn.net/M_H_T__/article/details/103263414