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;
}