HashTable

1.哈希表

理想的情况下是希望不经过任何比较,一次存取便能得到所查记录,那就必须在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使每个关键字和结构中一个唯一的存储位置相对应。因而在查找时,只要根据职工对应关系f找到给定值K的像f(K)。若结构中存在关键字和K相等的记录,则必定在f(K)的位置上,由此,不需要进行比较便可直接取得所查记录。在此,我们称这个对应关系f为哈希函数,按这个思想建立的表为哈希表。

2.常用的构造哈希函数的方法

1)直接定值法

取关键字或关键字的某个线性函数值为哈希地址。

H(key)=key或H(key)=a*key+b(其中a和b为常数)【这种哈希函数叫做自身函数】

2)平方取中法

3)折叠法

typedef int KeyType;

struct ElemType
{
	KeyType key;  // 
	void* ptr;	  // value
};

typedef struct
{
	ElemType data[m];
	int cursize;
}HashTable;

void Init_HashTable(HashTable* pt)
{
	assert(pt != nullptr);
	pt->cursize = 0;
	for (int i = 0; i < m; ++i)
	{
		pt->data[i].key = NIL;
		pt->data[i].ptr = nullptr;
	}
}
int Hash(KeyType kx)
{
	return kx % m; // m = 13;
}
int Inc(int i)
{
	return i;
}
int Hash_Inc(KeyType kx, int i)
{
	return (Hash(kx) + Inc(i)) % m;
}
bool Insert_Item(HashTable* pt, ElemType item)
{
	assert(pt != nullptr);
	for (int i = 0; i < m; ++i)
	{
		int index = Hash_Inc(item.key, i);
		if (pt->data[i].key == NIL)
		{
			pt->data[index] = item;
			pt->cursize += 1;
			return true;
		}
	}
	return false;
}

void * FindValue(HashTable* pt, KeyType kx)
{
	assert(pt != nullptr);
	for (int i = 0; i < m; ++i)
	{
		int pos = Hash_Inc(kx, i);
		if (pt->data[pos].key == kx)
		{
			return pt->data[pos].ptr;
		}
		if (pt->data[pos].key = NIL)
		{
			return nullptr;
		}
	}
	return nullptr;
}
int main()	
{
	HashTable ht;
	Init_HashTable(&ht);
	int ar[] = { 12,15,28,23,25,38,36,49,14 };
	int  n = sizeof(ar) / sizeof(ar[0]);
	for (int i = 0; i < n; ++i)
	{
		struct ElemType item = { ar[i],nullptr };
		bool tag = Insert_Item(&ht, item);
	}
}

1>线性探查法

2>二次探查法

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

#define m 13
typedef int KeyType;
typedef struct
{
	KeyType key;
	void* ptr;
}ElemType;
typedef struct HashNode
{
	ElemType data;
	struct HashNode* next;
}HashNode;

typedef struct
{
	HashNode* table[m];
	int cursize;
}HashTable;

int Hash(KeyType kx)   // "abc"; "bca";
{
	return kx % m;
}
void Init_Hash(HashTable* pt)
{
	assert(pt != nullptr);
	for (int i = 0; i < m; ++i)
	{
		pt->table[i] = nullptr;
	}
	pt->cursize = 0;
}
void Insert_Item(HashTable* pt, ElemType item)
{
	assert(pt != nullptr);
	int index = Hash(item.key);
	HashNode* s = (HashNode*)malloc(sizeof(HashNode));
	if (nullptr == s) exit(1);
	s->data = item;
	s->next = pt->table[index];
	pt->table[index] = s;
	pt->cursize += 1;
}
HashNode* FindValue(HashTable* pt, KeyType kx)
{
	int index = Hash(kx);
	HashNode* p = pt->table[index];
	while (p != nullptr && p->data.key != kx)
	{
		p = p->next;
	}
	return p;
}
void ClearHash(HashTable* pt)
{
}
void Remove(HashTable* pt, KeyType kx)
{
}
int main()
{
	int ar[] = { 1,55,19,20,10,11,14,68,84,23,27,79 };
	int n = sizeof(ar) / sizeof(ar[0]);

	HashTable ht;
	Init_Hash(&ht);

	for (int i = 0; i < n; ++i)
	{
		ElemType item = { ar[i],nullptr };
		Insert_Item(&ht, item);
	}
	KeyType kx;
	scanf_s("%d", &kx);
	HashNode* p = FindValue(kx);
	if (p != nullptr)
	{
	}
	return 0;
}

4.链式哈希
在这里插入图片描述

HashTable.cpp

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#define m 13
#define INC  2
typedef int KeyType;
typedef struct
{
	KeyType key;
	void* ptr;
}ElemType;	 //  key_value
typedef struct HashNode
{
	ElemType data;
	struct HashNode* next;
}HashNode;

typedef struct
{
	HashNode** table;
	int capacity;
	int total;
}HashTable;

int Hash(HashTable *pt,KeyType kx)   // "abc"; "bca";
{
	return kx % pt->capacity;
}
void Init_Hash(HashTable* pt)
{
	assert(pt != nullptr);
	pt->table = (HashNode**)malloc(sizeof(HashNode*) * m);
	if (pt->table == nullptr) exit(EXIT_FAILURE);
	pt->capacity = m;
	for (int i = 0; i < pt->capacity; ++i)
	{
		pt->table[i] = nullptr;
	}
	pt->total = 0;
}
HashNode* FindValue(HashTable* pt, KeyType kx)
{
	int index = Hash(pt,kx);
	HashNode* p = pt->table[index];
	while (p != nullptr && p->data.key != kx)
	{
		p = p->next;
	}
	return p;
}

bool Inc(HashTable* pt)
{
	int incsize = pt->capacity * INC;
	int oldsize = pt->capacity;
	HashNode** newdata = (HashNode**)malloc(sizeof(HashNode*) * incsize);
	if (newdata == nullptr) return false;
	for (int i = 0; i < incsize; ++i)
	{
		newdata[i] = nullptr;
	}
	pt->capacity = incsize;
	for (int i = 0; i < oldsize; ++i)
	{
		if (pt->table[i] != nullptr)
		{

		}
	}

}	
bool Insert_Item(HashTable* pt, ElemType item)
{
	assert(pt != nullptr);
	HashNode* p = FindValue(pt, item.key);
	if (p != nullptr) return false;
	if (pt->total > pt->capacity && !Inc(pt))
	{
		return false;
	}
	int index = Hash(item.key);
	HashNode* s = (HashNode*)malloc(sizeof(HashNode));
	if (nullptr == s) exit(1);
	s->data = item;
	s->next = pt->table[index];
	pt->table[index] = s;
	pt->total += 1;
	return true;
}
bool Remove(HashTable* pt, KeyType kx)
{
	assert(pt != nullptr);
	int index = Hash(kx);
	HashNode* pr = nullptr;
	HashNode* p = pt->table[index];
	while (p != nullptr)
	{
		if (p->data.key == kx)
		{
			if (pr != nullptr)
			{
				pr->next = p->next;
			}
			else
			{
				pt->table[index] = p->next;
			}
			free(p);
			pt->total -= 1;
			return true;
		}
		pr = p;
		p = p->next;
	}
	return false;
}
void ClearHash(HashTable* pt)
{
	for (int i = 0; i < m; ++i)
	{
		while (pt->table[i] != nullptr)
		{
			HashNode* q = pt->table[i];
			pt->table[i] = q->next;
			free(q);
		}
	}
	pt->total = 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值