开放定址散列表

Posted lineaar

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开放定址散列表相关的知识,希望对你有一定的参考价值。

// 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;
}

  

以上是关于开放定址散列表的主要内容,如果未能解决你的问题,请参考以下文章

散列表的开放定址法以及再散列法(C语言)

散列表解决冲突的方式

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

hash算法解决冲突的方案

散列——排解冲突 开放定址法(上)

算法小讲堂之哈希表|散列表|考研笔记