哈希表!是为了根据key值和哈希函数(一般是key值对tabsize取模),快速找到对应的数据而生,其数据结构组成如下:
#define DEFAULT_SIZE 128
typedef struct _listNode {
struct _listNode* next;
int key;
void* data;
}listNode;
typedef listNode* list;
typedef listNode* element;
typedef struct _hashTable {
int tableSize;
list* theLists;
}hashTable;
根据数据结构组成,其由哈希表头、哈希桶、数据结点组成,其中数据结点包含有键值、next指针和void*型的数据。list是哈希桶指针,element是数据结点指针,其实他们是一回事,只是为了区分而已。需要说明的哈希桶的data为空,key也只是占位的作用,起作用的是next指针,指向真正的listNode。
key---->哈希函数---->索引值(哈希桶的下标)---->哈希桶对应的列表–>找到对应的node结点
#include<Windows.h>
#include<iostream>
#include<stdio.h>
#include <string>
#include <string.h>
using namespace std;
#define DEFAULT_SIZE 128
typedef struct _listNode {
struct _listNode* next;
int key;
void* data;
}listNode;
typedef listNode* list;
typedef listNode* element;
typedef struct _hashTable {
int tableSize;
list* theLists;
}hashTable;
hashTable* initHash(int tableSize);
int hashFunction(int key, int tableSize);//哈希函数
element findElement(hashTable* hashTable, int key);
bool insertElement(hashTable* hashTable, int key,void* value);
bool deleteElement(hashTable* hastTable, int key);
int main() {
const char *str[] = { "如花",(char*)"小芳",(char*)"苍井空",(char*)"夏老师" };
char str1[] = { "如花" };
int i = 0;
hashTable* hashTab = initHash(30);
for (int i = 0; i < 4; i++) {
if (insertElement(hashTab, i,(char*) str[i])) {
cout << "插入成功!" << endl;
}
else {
cout << "插入失败!" << endl;
}
}
if (!deleteElement(hashTab, 3))
cout << "删除失败!" << endl;
for (int i = 0; i < 4; i++) {
element E = findElement(hashTab, i);
if (E) {
cout << "找到的元素为:" <<(char*)( E->data) << endl;
}
else
cout << "未找到key"<<i<<"对应的元素" << endl;
}
system("pause");
return 0;
}
hashTable* initHash(int tableSize) {
int i = 0;
hashTable* hTable = NULL;
if (tableSize <= 0) {
tableSize = DEFAULT_SIZE;
}
hTable = (hashTable*)malloc(sizeof(hashTable));
if (hTable == NULL) {
cout << "hashTable malloc failure" << endl;
return NULL;
}
hTable->tableSize = tableSize;
//为哈希桶分配内存空间,其为一个指针数组
hTable->theLists = (list*)malloc(tableSize * sizeof(list));
if (hTable->theLists == NULL) {
cout << "theLists malloc failure" << endl;
free(hTable);
return NULL;
}
//为哈希桶对应的指针数组初始化链表结点
for (int i = 0; i < tableSize; i++) {
hTable->theLists[i] = (listNode*)malloc(sizeof(listNode));
if (hTable->theLists[i] == NULL) {
cout << "theLists malloc failure" << endl;
free(hTable->theLists);
free(hTable);
return NULL;
}
memset(hTable->theLists[i], 0, sizeof(listNode));
}
return hTable;
}
int hashFunction(int key, int tableSize) {
/*根据 key 计算索引,定位 Hash 桶的位置*/
return (key % tableSize);
}
element findElement(hashTable* hashTable, int key) {
int i = 0;
list L = NULL;
element E = NULL;
i = hashFunction(key, hashTable->tableSize);
L = hashTable->theLists[i];
E = L->next;
while (E != NULL && E->key != key) {
E = E->next;
}
return E;
}
bool insertElement(hashTable* hashTable, int key, void* value) {
element E = NULL, tmp = NULL;
list L = NULL;
E = findElement(hashTable, key);
if (E == NULL) {
tmp = (listNode*)malloc(sizeof(listNode));
if (tmp == NULL) {
printf("listNode malloc failure!");
return false;
}
tmp->data = value;
tmp->key = key;
tmp->next = NULL;
L = hashTable->theLists[hashFunction(key,hashTable->tableSize)];
tmp->next = L->next;
L->next = tmp;
return true;
}
else {
cout << "element already exits" << endl;
return false;
}
}
bool deleteElement(hashTable* hashTable, int key) {
element E = NULL;
element pre = NULL;
int index = hashFunction(key, hashTable->tableSize);
pre = hashTable->theLists[index];
E = hashTable->theLists[index]->next;
while (E->key != key && E != NULL) {
pre = E;
E = E->next;
}
if (E) {
pre->next = E->next;
delete E;
return true;
}
return false;
}