1. C ,链表, 实现哈希表的删除,插入,添加,查询功能
(适合频繁的删除插入等操作)
#include <stdio.h>
#include<iostream>
#include<cstring>
#include < vector>
//#include "hash1.h"
using namespace std;
#define DEFAULT_SIZE 16
int COUNT = 0;
typedef struct _ListNode
{
int key;
void* data;
struct _ListNode* next;
}ListNode;
typedef ListNode* List; //为一种数据类型定义一个新名字
typedef ListNode* Element;
typedef struct _HashTable
{
int TableSize;
List* Thelists;
}HashTable;
int myHash(int key, int TableSize)
{
return (key % TableSize);
}
HashTable* InitHash(int TableSize);
Element Find(HashTable* HashTable, int present_key);
void Insert(HashTable* HashTable, int present_key, void* present_value);
void* Retrieve(Element e);
void Delete(HashTable* HashTable, int present_key, void* present_value); //哈希表元素删除
//初始化哈希表
HashTable* InitHash(int TableSize)
{
int i = 0;
HashTable* hTabel = NULL;
if (TableSize <= 0)
{
TableSize = DEFAULT_SIZE;
}
hTabel = (HashTable*)malloc(sizeof(HashTable));
if (hTabel == NULL)
{
printf("HashTable malloc error \n");
return NULL;
}
hTabel->TableSize = TableSize;
//为哈希桶的第一个元素分配内存,其为一个指针数组
hTabel->Thelists = (List*)malloc(sizeof(List) * TableSize);
if (NULL == hTabel->Thelists)
{
printf("HashTable malloc error \n");
free(hTabel);
return NULL;
}
//为哈希桶对应的指针数组初始化链表节点
for (int i = 0; i < TableSize; i++)
{
hTabel->Thelists[i] = (ListNode *)malloc(sizeof(ListNode));
if (NULL == hTabel->Thelists[i])
{
printf("HashTable malloc error \n");
free(hTabel->Thelists);
free(hTabel);
return NULL;
}
else
{
memset(hTabel->Thelists[i], 0, sizeof(ListNode)); //把分配的内存里面的东西都设置为0
}
}
return hTabel;
}
//会根据键值查找元素
Element Find(HashTable* HashTable, int present_key)
{
int i = 0;
List L = NULL;
Element e = NULL;
i = myHash(present_key, HashTable->TableSize); //计算当前的元素对应的键指在第几个分类数组里
L = HashTable->Thelists[i]; //将找到的数组的索引给L,也即时数组的头节点
e = L->next;
while (e != NULL && e->key != present_key)
e = e->next;
return e;
}
//向哈希表插入元素,void* present_value:可以擦汗如任意形式的键值
void Insert(HashTable* HashTable, int present_key, void* present_value)
{
Element e = NULL, temp = NULL;
List L = NULL;
e = Find(HashTable, present_key);
if (e == NULL)
{
temp = (Element)malloc(sizeof(ListNode));
if (temp == NULL)
{
printf(" malloc error \n");
}
//判断当前键值在第几个数组myHash(present_key, HashTable->TableSize)
//对应的就是键值所在数组的地址,也即是第一个元素的地址
L = HashTable->Thelists[myHash(present_key, HashTable->TableSize)];
//前插法
temp->data = present_value;
temp->key = present_key;
temp->next = L->next;
L->next = temp;
COUNT += 1;
}
else
{
printf(" key is already exist \n");
}
}
//哈希表元素删除
void Delete (HashTable* HashTable, int present_key, void* present_value)
{
Element e = NULL, previous = NULL;
List L = NULL;
int i = myHash(present_key, HashTable->TableSize);
//将此节点指向索引值所在数组的第一个元素
L = HashTable->Thelists[i];
previous = L;
e = L->next;
while(e != NULL && e->key != present_key)
{
previous = e; //记录前一个节点
e = e->next;
}
if (e) //如果键值存在
{
previous->next = e->next;
free(e);
}
}
//哈希表元素提取
void* Retrieve(Element e)
{
return e ? e->data : NULL;
}
void Print(HashTable* HashTable)
{
if (HashTable == NULL)
{
printf(" Table is empty \n");
}
else
{
for (int i = 1; i <= COUNT; i++)
{
Element e= Find(HashTable, i);
if (e)
{
printf("key = %d\n", i);
printf("value = %s\n", (const char*)Retrieve(e));
}
else
{
printf("key = %d not found\n",i);
}
}
}
printf("******************** finish\n");
}
int main()
{
const char *elems[] = { "翠花","小芳","苍老师" }; //指针数组
HashTable* HashTable = NULL;
HashTable = InitHash(30);
Insert(HashTable, 1, (char*)elems[0]);
Insert(HashTable, 2, (char*)elems[1]);
Insert(HashTable, 3, (char*)elems[2]);
Print(HashTable);
Delete(HashTable,2, (char*)elems[1]);
Print(HashTable);
return 0;
}
2 C数组实现 哈希表删除,插入等等功能
(适合长度固定,数据一次性给完,数据比较少的情况)
3 例题汇总
(1)原地哈希 442数组中的重复元素
https://blog.csdn.net/weixin_43528481/article/details/129916692?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22129916692%22%2C%22source%22%3A%22weixin_43528481%22%7D