#include<iostream.h>
#include<stdlib.h>
const int MapSize = 1024;
struct hashmap_ele
{
int key; //key
int value; //value
int in_use; //开始时位置上无元素,未被占用
hashmap_ele * multis; //hash地址相同的值,通过索引链接他
};
struct hash_map
{
int table_size; //总大小
int size; //当前的大小
hashmap_ele * date; //数据的链接
};
hash_map * map_head;
//MyList类
class MyList
{
public:
hash_map * CreateHashMap(); //创建HashMap
int GetPosition(hash_map *m, int key); //计算键值对存储的位置
bool IsInUse(hash_map *m, int key); //判断位置上是否已经有元素
int IsKeyExists(hash_map *m, int key); //判断map中是否已经存在该键
void SetKey(int key, int val); //加入键值对
void DisEntry(hash_map *m); //打印所有的键值对
void DeleteKey(int key); //删除指定的键值对
int SearchKey(int key); //搜索出与指定键对应的值
int GetMapSize();
void ShowInfo(hash_map * m); //输出map的相关信息
};
//创建HashMap
hash_map * MyList::CreateHashMap()
{
hash_map *m;
m = (hash_map *)malloc(sizeof(hash_map)); //创建HashMap,分配空间
m->date = (hashmap_ele *)calloc(MapSize, sizeof(hashmap_ele)); //为HashMap的数据分配空间,初始空间为1024
m->table_size = MapSize; //指定总的大小
m->size = 0; //指定当前的大小
return m;
}
//得到key的存储位置
int MyList::GetPosition(hash_map *m, int key) //得到键值对存储的位置
{
key += (key << 12);
key ^= (key >> 22);
key += (key << 4);
key ^= (key << 9);
key += (key << 10);
key ^= (key >> 2);
key += (key << 7);
key ^= (key >>12);
key = (key >> 3) * 2654435761;
key %=m->table_size;
if(key < 0)
key = -key;
return key;
}
/*
判断第一个位置上是否已经有元素
*/
bool MyList::IsInUse(hash_map *m, int key)
{
int curr;
curr = GetPosition(m, key);
if(m->date[curr].multis == NULL) //第一个位置未被占用
return false;
else //第一个位置被占用
return true;
}
/*
判断key是否已在HashMap中存在
*/
int MyList::IsKeyExists(hash_map *m, int key)
{
int pos;
int flag = 0;
int record = 1; //记录节点在链中的那个位置
hashmap_ele * e;
pos = GetPosition(m, key);
if(m->table_size == m->size){
int size = MapSize;
realloc(m, size+=size);
}
if(!IsInUse(m, key)) //第一个位置没有被占用,map中没有该键
{
return 0;
}else{ //第一个位置被占用,存在一个键,检查他的hashmap_ele * multis指针
if(m->date[pos].multis->key == key) //第一个位置上元素的键就是,已经存在,返回true;
return record;
else{ //第一个键不是,要向下检查
if((e = m->date[pos].multis->multis) != NULL) //还有其他的元素
{
do{
++record;
if(e->key == key){
flag = 1;
break;
}
}while((e = e->multis) != NULL);
}
else //键不相等,并且hashmap_ele * multis指针为空,不存在该键
return 0;
if(flag == 1)
return record;
else
return 0;
}
}
}
/*
向HashMap中插入一键值对
*/
void MyList::SetKey(int key, int val)
{
hash_map * m; //hash_map 的变量
hashmap_ele *e, *add; //hashmap_ele 的变量
int pos;
add = (hashmap_ele *)malloc(sizeof(hashmap_ele));
add->key = key;
add->value = val;
add->in_use = 1;
add->multis = NULL;
m = map_head;
pos = GetPosition(m, key);
if(m->date == NULL) //HashMap为空
cout<<"The hashmap is not create !"<<endl;
else{
if(!IsKeyExists(map_head, key)) // map中没有该键
{
e = m->date[pos].multis; //指向第一个位置,不管第一个位置占用还是不占用
m->size++;
if(!IsInUse(map_head, key)) //第一个位置未被占用
{
m->date[pos].multis = add;
}
else{ //第一个位置被占用
while(e->multis != NULL)
{
e = e->multis;
}
e->multis = add;
}
}else{ //map中该键值已经存在
cout<<"该键已经在map中存在,插入失败!"<<endl;
}
}
}
/*
打印出HashMap中的键值对
*/
void MyList::DisEntry(hash_map * m)
{
hashmap_ele * e1, * e2;
e1 = m->date; //e1指向了存储位置
for(int i = 0; i < m->table_size; i++)
{
if((e1 + i)->multis != NULL)
{
e2 = (e1 + i)->multis; //e2指向了第一个位置
do{
cout<<e2->key<<"-->"<<e2->value<<endl;
e2 = e2->multis;
}while(e2 != NULL);
}
}
}
/*
删除指定的key
*/
void MyList::DeleteKey(int key)
{
int record;
int pos;
hashmap_ele * e, *efree;
hash_map *m;
m = map_head;
record = IsKeyExists(m, key);
pos = GetPosition(m, key);
if(!record){
cout<<"map中没有指定的key值 !"<<endl;
}else{
e = &(m->date[pos]); //将存储位置赋值给e
for(int i = 1; i <= record -1; i++)
{
e = e->multis;
}
efree = e->multis->multis;
e->multis = NULL; //将位置指向NULL,不再指向删除的节点
--(m->size); //将map的当前键值对减1
free(efree); //释放删除节点的内存
cout<<"删除键值成功!"<<endl;
}
}
/*
获取键为key的值
*/
int MyList::SearchKey(int key)
{
int record;
int pos;
hashmap_ele *e;
hash_map *m;
m = map_head;
pos = GetPosition(m, key);
record = IsKeyExists(m, key);
if(!record){
cout<<"map中不存在此键!"<<endl;
return 0;
}else{
e = &(m->date[pos]); //将存储位置赋值给e
for(int i = 1; i <= record; i++)
{
e = e->multis;
}
return e->value;
}
}
/*
获取map当前有多少键值对
*/
int MyList::GetMapSize()
{
return map_head->size;
}
/*
获取map中的当前信息
*/
void MyList::ShowInfo(hash_map * m)
{
cout<<"当前map中的键值对个数:"<<m->size<<endl;//输出当前map中的键值对个数
cout<<"当前map中的键值对:"<<endl;
DisEntry(m); //打印出当前map中的键值对
}
/*
主函数
*/
int main(void)
{
MyList myList;
int addKey;
int addValue;
int delKey;
int searchKey;
int searchValue;
/*
创建HashMap
*/
cout<<"创建一个新map:"<<endl;
map_head = myList.CreateHashMap();
cout<<"map的总大小:"<<map_head->table_size<<endl;
cout<<"map的当前大小(当前map中的键值对):"<<map_head->size<<endl;
cout<<"-------------------------------------------"<<endl;
/*
增加一对键值到哈希表中
*/
cout<<"插入两个键值对(1025, 23)(99999,23):"<<endl;
myList.SetKey(1025, 23);
myList.SetKey(99999, 23);
myList.ShowInfo(map_head);//输出map的相关信息
cout<<"输入所插入的键(数值类型):"<<endl;
cin>>addKey;
cout<<"输入所插入的值(数值类型):"<<endl;
cin>>addValue;
myList.SetKey(addKey, addValue);
cout<<"已插入键值对:("<<addKey<<","<<addValue<<")"<<endl;
myList.ShowInfo(map_head);//输出map的相关信息
cout<<"-------------------------------------------"<<endl;
/*
删除键为key的单元
*/
cout<<"请输入要删除的键:"<<endl;
cin>>delKey;
myList.DeleteKey(delKey); //删除指定的delKey
myList.ShowInfo(map_head);//输出map的相关信息
cout<<"-------------------------------------------"<<endl;
/*
获取与指定键对应的值
*/
cout<<"请输入要获取的键:"<<endl;
cin>>searchKey;
searchValue = myList.SearchKey(searchKey);
cout<<"您要搜寻的键的值为:"<<searchValue<<endl;
cout<<"-------------------------------------------"<<endl;
/*
获取map当前有多少键值对
*/
cout<<"map中当前键值对的个数为:"<<myList.GetMapSize()<<endl;
return 0;
}
hash_map C++实现
最新推荐文章于 2024-01-20 10:44:19 发布