散列表的C语言实现-开放定址法

头文件:

#ifndef __HASHTABLE_H
#define __HASHTABLE_H

/*********************(平方)开放定址散列法***************/

//如果有冲突发生,那么就尝试另外的单元,直到找到空的单元为止
typedef unsigned int index;
typedef index position;
typedef int ElementType;
#define MINTABLESIZE 5

struct hashTable;
typedef struct HashTable *hashTable;

hashTable initializeTable(int tableSize);
void destoryTable(hashTable H);
position find(ElementType key,hashTable H);
void insert(ElementType key,hashTable H);
ElementType retrieve(position p,hashTable H);
hashTable reHash(hashTable H);
int Delete(ElementType key,hashTable H);
int nextPrime(int tableSize);
int isPrime(int x);
int Hash(ElementType key,int tableSize);

enum kindOfEntry{legitimate,empty,deleted};

struct hashEntry
{
	ElementType element;
	enum kindOfEntry info;
};

typedef struct hashEntry cell;

struct HashTable
{
	int tableSize;
	cell *theCells;
};
#endif

实现文件:

#include "HashTable.h"
#include <stdio.h>
#include <stdlib.h>

/***********************开发定址法(平方)***********************************/
hashTable initializeTable(int tableSize)
{
	hashTable table;
	int i;
	if(tableSize<MINTABLESIZE)
	{
		printf("table size is too small\n");
		exit(-1);
	}
	table=(hashTable)malloc(sizeof(struct HashTable));
	if(!table)
	{
		printf("out of space\n");
		exit(-1);
	}
	table->tableSize=nextPrime(tableSize);
	table->theCells=(cell*)malloc(sizeof(cell)*table->tableSize);
	if(!table->theCells)
	{
		printf("out of space\n");
		exit(-1);
	}
	for(i=0;i<table->tableSize;i++)
		table->theCells[i].info=empty;

	return table;
}

void destoryTable(hashTable H)
{
	free(H->theCells);
	H=NULL;
}

position find(ElementType key,hashTable H)
{
	position currentPos;
	int collisionNum;

	collisionNum=0;
	currentPos=Hash(key,H->tableSize);
	while(H->theCells[currentPos].info!=empty&&
		H->theCells[currentPos].element!=key)
	{
		//平方探测法
		currentPos+=2*collisionNum-1;
		if(currentPos>=H->tableSize)
			currentPos-=H->tableSize;
	}
	return currentPos;
}

int Delete(ElementType key,hashTable H)
{
	position pos;
	pos=find(key,H);
	if(H->theCells[pos].info==empty)
		return 0;
	else
	{
		H->theCells[pos].info=deleted;
		return 1;
	}
}

void insert(ElementType key,hashTable H)
{
	position pos;
	pos=find(key,H);
	if(H->theCells[pos].info!=legitimate)
	{
		H->theCells[pos].info=legitimate;
		H->theCells[pos].element=key;
	}
}

ElementType retrieve(position p,hashTable H)
{

}

hashTable reHash(hashTable H)	//再散列
{
	int i,oldSize;
	cell *oldCells;

	oldCells=H->theCells;
	oldSize=H->tableSize;

	H=initializeTable(2*oldSize);
	for(i=0;i<oldSize;i++)
	{
		if(oldCells[i].info==legitimate)
			insert(oldCells[i].element,H);
	}
	free(oldCells);
	return H;
}
int nextPrime(int tableSize)
{
	while(1)
	{
		if(isPrime(tableSize))
			return tableSize;
		else
			tableSize++;
	}
}
int isPrime(int x)
{
	int i;
	for(i=2;i*i<=x;i++)
	{
		if(x%i==0)
			return 0;
	}
	return 1;
}
int Hash(ElementType key,int tableSize)
{
	return key%tableSize;
}
/**************************************************************************/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-07 14:37:39

散列表的C语言实现-开放定址法的相关文章

散列表的C语言实现-分离链接法

一:散列表的定义: 散列表的实现常常叫做散列,散列是一种用于以常数平均时间执行插入,查找,删除的技术,但是,那些需要元素间任何排序信息的操作将不会得到支持,如findmin,findmax等等.散列表的优点很明显,它的查询时间为常数,速度非常快,缺点就是元素间没有排序,对于一些需要排序的场合不适用.理想的散列表数据结构就是一个包含有关键字的具有固定大小的数组,用一个散列函数来跟据关键字的值来将关键字插入到表中.这是散列的基本想法,剩下的问题是要选择一个好的散列函数,当俩个关键字散列到同一个值得时

数据结构--开放定址法解决散列冲突时几种探测法的比较

开放定址法解决散列冲突时主要有线性探测法,平方探测法和双散列法,以下代码通过插入大量随机数,来统计几种探测法产生冲突的次数. #include<iostream> using namespace std; #define MinTablesize 10 #define Num 3000 typedef unsigned int Index; typedef Index Position; struct Hashtal; typedef struct Hashtal *Hashtable; in

数据结构之散列(开放定址法)

1 // OHash 2 // 关键字:int 3 // Hash函数:hash(X) = X mod TableSize 4 // 冲突解决方法:开放定址法.Index(X, i) = (hash(X) + f(i)) mod TableSize, f(0) = 0 5 // 其中f(i)为: 6 // 1. 线性, f(i) = i 7 // 2. 平方, f(i) = i ^ 2 8 // 3. 双散列, f(i) = i * hash2(X), hash2(X, R) = R - (X

C# Dictionary源码剖析---哈希处理冲突的方法有:开放定址法、再哈希法、链地址法、建立一个公共溢出区等

参考:https://blog.csdn.net/exiaojiu/article/details/51252515 http://www.cnblogs.com/wangjun1234/p/3719635.html 源代码版本为 .NET Framework 4.6.1 Dictionary是Hashtable的一种泛型实现(也是一种哈希表)实现了IDictionary泛型接口和非泛型接口等,将键映射到相应的值.任何非 null 对象都可以用作键.使用与Hashtable不同的冲突解决方法,D

哈希表(开放定址法处理冲突)(1013)

Description 采用除留余数法(H(key)=key %n)建立长度为n的哈希表,处理冲突用开放定址法的线性探测. Input 第一行为哈希表的长度n: 第二行为关键字的个数: 第三行为关键字集合: 第三行为要查找的数据. Output 如果查找成功,输出关键字所哈希表中的地址和比较次数:如果查找不成功,输出-1. 如果查找成功,输出关键字所哈希表中的地址和比较次数:如果查找不成功,输出-1. Sample Input   1 2 3 4 5 13 11 16 74 60 43 54 9

数据结构(Java语言)——HashTable(开放定址法)简单实现

分离链接散列算法的缺点是使用一些链表.由于给新单元分配地址需要时间,因此这就导致算法的速度有些减慢,同时算法实际上还要求对第二种数据结构的实现.另有一种不用链表解决冲突的方法是尝试另外一些单元,直到找出空的单元为止.更常见的是,单元h0(x),h1(x),h2(x),...相继被试选,其中hi(x)=(hash(x)+f(i)) mod TableSize,且f(0)=0.函数f是冲突解决方法,因为所有的数据都要置于表内,所以这种解决方案所需要的表要比分离链接散列的表大.一般来说,对于不使用分离

算法:开放定址法散列表

hash.h #ifndef _HASHQUAD_H #define _HASHQUAD_H #define MinTableSize 10 struct HashEntry; struct HashNode; typedef char *ElementType; typedef unsigned int Index; typedef Index Position; typedef struct HashNode *HashTable; typedef struct HashEntry *Cel

开放定址法构造哈希表

#define NULLKEY -1 #define DELKEY -2 typedef int KeyType; typedef struct { KeyType key; int count;//探测次数域 }HashTable; void InsertHT(HashTable HT[], KeyType k, int& n, int m, int p) { //n哈希表中总元素的个数,m表长 int i, adr; adr = k % p; if (HT[adr].key == NULLK

数据结构之散列表总结

散列表的概念 注意:    ①由同一个散列函数.不同的解决冲突方法构造的散列表,其平均查找长度是不相同的.     ②散列表的平均查找长度不是结点个数n的函数,而是装填因子α(填入表中的记录个数/散列表的槽数    n/m).因此在设计散列表时可选择α以控制散列表的平均查找长度.(平均查找长度=总查找(插入)/记录个数)          通过链接法解决冲突:成功查找的期望查找长度O(1+a), 不成功查找的平均查找长度也为O(1+a).         开放寻址解决冲突:引入探查序列,对于a<