大家好,这里是国中之林!
❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看←
哈希表的顺序存储实现
一.哈希顺序表的原理
上一章是哈希链表,这一次我们结合顺序表,来一个哈希顺序表.
当我们不需要大量的删除和插入数据时,那么这种哈希顺序表的优点就比哈希链表大.
二.哈希顺序表的结构
还记得我们哈希链表的结构嘛?
就像这样,那么我们的哈希顺序表就只是这样的:
结构代码:
哈希表数组里面直接是顺序表,顺序表中是数据.
三.哈希顺序表的算法实现
1.哈希函数
还是老样子,算出在那个数组中.
2.哈希表的初始化
先动态分配哈希表.
然后,动态分配数组.
最后动态分配顺序表并初始化顺序表.
3.哈希表查找元素
先找到在那个数组中,然后遍历顺序表对比.
4.顺序表的接口
我们哈希表的插入和删除就是对顺序表的插入和删除,所以我们来设置顺序表接口.
①.顺序表插入
③.顺序表删除
还记得乾坤大罗伊吧,哈哈,删除就是往前移动,删除边界值,直接减减.
5.哈希表插入元素
哈希函数找到目标顺序表,然后姚先判断关键值存不存在,不存在才可以插入.
6.哈希表删除元素
先找到目标顺序表,然后依次遍历对比删除.
7.哈希表元素中提取数据
8.哈希表的销毁
四.完整代码
#include <iostream>
using namespace std;
#define DEFAULT_SIZE 8 //哈希桶索引大小
#define Max_size 6
typedef struct _Element
{
void* data;
int key;
}Element;
typedef struct _SqList
{
Element* elems; //基地址
int length; //元素个数
int size; //总的空间大小
}SqList;
typedef struct _HashTable
{
int TableSize;
SqList* Thelists;
}HashTable;
//哈希函数
int Hash(int key, int TableSize)
{
return (key % TableSize);
}
// 初始化哈希表
HashTable* InitHash(int TableSize)
{
HashTable* hTable = NULL;
if (TableSize <= 0)
{
TableSize = DEFAULT_SIZE;
}
hTable = new HashTable;
if (NULL == hTable)
{
cout << "HashTable malloc error.\n";
return NULL;
}
hTable->TableSize = TableSize;
// 为Hash桶分配内存空间,SqList数组
hTable->Thelists = new SqList[TableSize];
if (NULL == hTable->Thelists)
{
cout << "HashTable malloc error.\n";
delete hTable;
return NULL;
}
for (int i = 0; i < TableSize; i++)
{
hTable->Thelists[i].elems = new Element[Max_size];
if (NULL == hTable->Thelists[i].elems)
{
cout << "HashTable malloc error.\n";
delete[] hTable->Thelists;
delete hTable;
return NULL;
}
else
{
hTable->Thelists[i].length = 0;
hTable->Thelists[i].size = Max_size;
memset(hTable->Thelists[i].elems, 0, sizeof(hTable->Thelists[i].elems));
}
}
return hTable;
}
//哈希表查找元素
bool Find(HashTable* HashTable, int key, int& pos)
{
int i = Hash(key, HashTable->TableSize);
int length = HashTable->Thelists[i].length;
for (int j = 0; j < length; j++)
{
if (HashTable->Thelists[i].elems[j].key == key)
{
pos = j;
return true;
}
}
return false;
}
//顺序表插入元素
bool InsertSqList(SqList& l, Element& e)
{
if (l.length == l.size) return false;
l.elems[l.length++] = e;
return true;
}
//顺序表删除元素
bool listDelete(SqList& l, int i)
{
if (i < 0 || i >= l.length) return false;
l.elems[i].key = 0;
l.elems[i].data = NULL;
if (i == l.length - 1) //边界值
{
l.length--;
return true;
}
for (int c = i; c < l.length - 1; c++)
{
l.elems[c] = l.elems[c + 1];
}
l.length--;
return true;
}
//哈希表插入元素
void Insert(HashTable* HashTable, int key, void* value)
{
int i = Hash(key, HashTable->TableSize);
int a = 0;
if (Find(HashTable, key, a))
{
cout << "the key already exist\n";
}
else
{
Element e;
e.data = value;
e.key = key;
if (InsertSqList(HashTable->Thelists[i], e))
{
cout << "插入[" << key << "]" << "成功..." << endl;
}
else
{
cout << "插入[" << key << "]" << "失败..." << endl;
}
}
}
//哈希链表删除元素
void Delete(HashTable* HashTable, int key)
{
int i = Hash(key, HashTable->TableSize);
int length = HashTable->Thelists[i].length;
for (int j = 0; j < length; j++)
{
if (HashTable->Thelists[i].elems[j].key == key)
{
if (listDelete(HashTable->Thelists[i], j))
{
cout << "删除成功!" << endl;
}
else
{
cout << "删除失败!" << endl;
}
}
}
}
//哈希表元素中提取数据
void* Retrieve(Element e)
{
return e.data;
}
//哈希表的销毁
void Destory(HashTable* HashTable)
{
int i = 0;
Element* L = NULL;
for (int i = 0; i < HashTable->TableSize; i++)
{
L = HashTable->Thelists[i].elems;
delete[] L;
}
delete[] HashTable->Thelists;
delete HashTable;
}
int main(void)
{
int b = 0, d = 0;
char* elems[] = { (char*)"大姚", (char*)"小美", (char*)"大美" };
HashTable* HashTable = NULL;
HashTable = InitHash(0);
Insert(HashTable, 1, elems[0]);
Insert(HashTable, 2, elems[1]);
Insert(HashTable, 3, elems[2]);
Delete(HashTable, 3);
for (int i = 0; i < 4; i++)
{
if (Find(HashTable, i, b))
{
d = Hash(i, HashTable->TableSize);
Element e = HashTable->Thelists[d].elems[b];
cout << "提取数据成功:" << (const char*)Retrieve(e) << endl;
}
else
cout << "提取数据失败,key[" << i << "]\n";
}
return 0;
}
运行结果: