开放定址散列表

// kaifangliaobiao.cpp : 定义控制台应用程序的入口点。
//使用平方探测解决冲突问题时,散列表至少空一半时,总能插入一个新的元素

#include "stdafx.h"
#include<iostream>
using namespace std;

#ifndef HashQuad
typedef unsigned int Index;
typedef Index Position;

struct HashTbl;
typedef struct HashTbl *HashTable;

HashTable InitializeTable(int TableSize);
void DestroyTable(HashTable H);
Position Find(int key, HashTable H);
void Insert(int key, HashTable H);
int Retrieve(Position P, HashTable H);
HashTable Rehash(HashTable H);
#endif // !HashQuad
#define MinTableSize 10

enum KindOfEntry{Legitimate,Empty,Delete};

struct HashEntry
{
	int key;
	enum KindOfEntry Info;
};

typedef struct HashEntry Cell;

struct HashTbl
{
	int TableSize;
	Cell *TheCell;
};

int Hash(int key, int tableSize)
{
	return key%tableSize;
}

int NextPrime(int n)
{
	if (n % 2 == 0) n++;               //1.排除掉偶数
	for (;; n += 2)
	{
		bool isPrime = 1;              //2.标志位
		for (int i = 3; i*i <= n; i += 2)
			if (n%i == 0) {
				isPrime = 0;
				break;
			}
		if (isPrime)
			return n;
	}
}

HashTable InitializeTable(int TableSize)   //初始化函数
{
	HashTable H;
	int i;

	if (TableSize < MinTableSize)
	{
		cout << "Table is too small";
		return NULL;
	}

	H = (HashTable)malloc(sizeof(HashTbl));                //1.初始化散列表地址
	if (H == NULL)
		cout << "out of space";

	H->TableSize = NextPrime(TableSize);                 //2.用素数初始化散列表大小

	H->TheCell = (Cell *)malloc(sizeof(Cell)*H->TableSize);  //3.申请一个表头
	if (H->TheCell == NULL)
		cout << "out of space";
	for (i = 0; i < H->TableSize; i++)
		H->TheCell[i].Info = Empty;                       //4.为每一个表项赋状态空
	return H;
}

Position Find(int key, HashTable H)                 //用平方探测散列法查找
{
	Position CurrentPos;                            //1.要返回的地址
	int CollisionNum;                               //2.偏移的位置量

	CollisionNum = 0;
	CurrentPos = Hash(key, H->TableSize);
	while (H->TheCell[CurrentPos].Info!=Empty&&H->TheCell[CurrentPos].key!=key)  //3.检测表项状态
	{
		CurrentPos += 2 * ++CollisionNum - 1;                                //4.偏移
		if (CurrentPos >= H->TableSize)                                     //5.满则折返
			CurrentPos -= H->TableSize;
	}
	return CurrentPos;
}

void Insert(int key, HashTable H)
{
	Position Pos;

	Pos = Find(key, H);
	if (H->TheCell[Pos].Info != Legitimate)
	{
		H->TheCell[Pos].Info = Legitimate;
		H->TheCell->key = key;
	}
}

HashTable Rehash(HashTable H)            //再散列
{
	int i, oldSize;
	Cell *OldCells;

	OldCells = H->TheCell;                  //1.记录旧散列表的信息
	oldSize = H->TableSize;

	H = InitializeTable(2 * oldSize);       //2.创建两倍大小的新散列表

	for (i = 0; i < oldSize; i++) {         //3.循环复制信息
		if (OldCells[i].Info == Legitimate)
			Insert(OldCells[i].key, H);
	}
	free(OldCells);
	return H;
}

int main()
{
    return 0;
}

  

时间: 2024-10-23 06:54:22

开放定址散列表的相关文章

数据结构与算法分析-开放定址散列表的实现

#include<stdio.h> #include"fatal.h" typedef char* ElementType; typedef unsigned int Index; typedef Index Position; struct HashTbl; typedef struct HashTbl *HashTable; HashTable InitializeTable(int TableSize); void DestroyTable(HashTable H);

Python数据结构——散列表

散列表的实现常常叫做散列(hashing).散列仅支持INSERT,SEARCH和DELETE操作,都是在常数平均时间执行的.需要元素间任何排序信息的操作将不会得到有效的支持. 散列表是普通数组概念的推广.如果空间允许,可以提供一个数组,为每个可能的关键字保留一个位置,就可以运用直接寻址技术. 当实际存储的关键字比可能的关键字总数较小时,采用散列表就比较直接寻址更为有效.在散列表中,不是直接把关键字用作数组下标,而是根据关键字计算出下标,这种 关键字与下标之间的映射就叫做散列函数. 1.散列函数

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

头文件: #ifndef __HASHTABLE_H #define __HASHTABLE_H /*********************(平方)开放定址散列法***************/ //如果有冲突发生,那么就尝试另外的单元,直到找到空的单元为止 typedef unsigned int index; typedef index position; typedef int ElementType; #define MINTABLESIZE 5 struct hashTable; t

【算法导论】学习笔记——第11章 散列表

11.1 直接寻址表当关键字的全域U很小,可采用直接寻址的方式.假设动态集合S的元素都取自全域U={0, 1, ..., m-1}的一个关键字,并且没有两个元素具有相同的关键字.为表示动态集合,使用直接寻址表(diret-address table),记为T[0...m-1],其中的每个位置称为槽(slot).直接寻找表就是按照数组索引,缺点明显.基本操作如下: 1 DIRECT-ADDRESS-SEARCH(T, k) 2 return T[k] 3 4 DIRECT-ADDRESS-INSE

散列表(算法导论笔记)

散列表 直接寻址表 一个数组T[0..m-1]中的每个位置分别对应全域U中的一个关键字,槽k指向集合中一个关键字为k的元素,如果该集合中没有关键字为k的元素,则T[k] = NIL 全域U={0,1,…,9}中的每个关键字都对应于表中的一个下标值,由实际关键字构成的集合K={2,3,5,8}决定表中的一些槽,这些槽包含指向元素的指针,而另一些槽包含NIL 直接寻址的技术缺点非常明显:如果全域U很大,则在一台标准的计算机可用内存容量中,要存储大小为|U|的一张表T也许不太实际,甚至是不可能的.还有

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

开放定址法解决散列冲突时主要有线性探测法,平方探测法和双散列法,以下代码通过插入大量随机数,来统计几种探测法产生冲突的次数. #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

散列表的开放寻址法

开放寻址法(open addressing)中,所有元素都存放在槽中,在链表法散列表中,每个槽中保存的是相应链表的指针,为了维护一个链表,链表的每个结点必须有一个额外的域来保存它的前戏和后继结点.开放寻址法不在槽外保存元素,不使用指针,也不必须为了维护一个数据结构使用额外的域,所有可以不用存储指针而节省的空间,使得可以用同样的空间来提供更多的槽,也潜在地减少了冲突,提高了检索速度. 为了使用开放寻址法插入一个元素,需要连续地检查散列表,或称为探查(probe),直到找到一个空槽来放置待插入的关键

散列表(数据结构学习笔记)

散列 散列表的一般实现叫散列.是一种以常数平均时间执行插入.删除.查找的技术.理想的散列表结构是一个包含关键字具有固定大小的数组.典型情况是,一个关键字就是一个带有相关值的字符串.把表大小记MaxSize,通常使表在0-MaxSize之间变化.每个关键字都被映射到0-MaxSize之间的某个单元中.这个映射关系就是散列函数.理想情况函数保证任何关键字都映射到不同单元里,实践是不可能的.因数组有限大小,而关键字可无限多.因此要找德散列函数尽可能的使关键字均匀的分布在单元中.如图 git在0号单元,