为了提高开发团队精神,缓解工作压力,某 IT 公司组织开发团队的 12 位男同事和测试团队 的 12 位女同事开展真人 CS 4vs4 野战联谊!面对性感的女同事,男同事们个个摩拳擦掌,跃跃欲 试!
野战活动那天,根据男女搭配,干活不累的原则,带队的专业教练让男同事站成一排,女同 事站成一排,然后要求从女生这排开始从 1 开始报数,每个报数的队员都要记住自己的编号: 1, 2, 3,4。。。。。。林子里响起了百灵鸟般的报数声!
报数时,教练发给每人一个白色的臂章贴在肩膀上,每个臂章上写着报数人自己报过的编号!
当所有人都报完数后,教练发出命令将 24 人均分成 6 个组!
编号除 6 能整除的为第一组: 6 12 18 24
编号除 6 余数为 1 的为第二组: 1 7 13 19
编号除 6 余数为 2 的为第三组: 2 8 14 20
编号除 6 余数为 3 的为第四组: 3 9 15 21
编号除 6 余数为 4 的为第五组: 4 10 16 22
编号除 6 余数为 5 的为第六组: 5 11 17 23
通过这种编号方式划分队列,无论队员归队,还是裁判确89认79队43员8身40份1,11都1非常方便,此后林 子里传来隆隆的笑声和枪炮声! 这种编号的方式就是高效的散列,我们俗称“哈希”! 以上过程是通过把关键码值 key(编号)映射到表中一个位置(数组的下标)来访问记录,以加 快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
哈希表 - 散列表,它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法
键(key): 组员的编号 如, 1 、 5 、 19 。 。 。
值(value): 组员的其它信息(包含 性别、年龄和战斗力等)
索引: 数组的下标(0,1,2,3,4) ,用以快速定位和检索数据
哈希桶: 保存索引的数组(链表或数组),数组成员为每一个索引值相同的多个元素
哈希函数: 将组员编号映射到索引上,采用求余法 ,如: 组员编号 19
- #define DEFAULT_SIZE 16
-
- 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;
- /*根据 key 计算索引,定位 Hash 桶的位置*/
- int Hash(int key, int TableSize)
- {
- return (key%TableSize);
- }
- /*初始化哈希表*/
- HashTable *InitHash(int TableSize)
- {
- int i = 0;
- HashTable *hTable = NULL;
-
- if (TableSize <= 0) {
- TableSize = DEFAULT_SIZE;
- }
-
- hTable = (HashTable *)malloc(sizeof(HashTable));
- if (NULL == hTable)
- {
- printf("HashTable malloc error.\n");
- return NULL;
- }
-
- hTable->TableSize = TableSize;
-
- //为 Hash 桶分配内存空间,其为一个指针数组
- hTable->Thelists = (List *)malloc(sizeof(List)*TableSize);
- if (NULL == hTable->Thelists)
- {
- printf("HashTable malloc error\n");
- free(hTable);
- return NULL;
- }
-
- //为 Hash 桶对应的指针数组初始化链表节点
- for (i = 0; i < TableSize; i++)
- {
- hTable->Thelists[i] = (ListNode *)malloc(sizeof(ListNode));
- if (NULL == hTable->Thelists[i])
- {
- printf("HashTable malloc error\n");
- free(hTable->Thelists);
- free(hTable);
- return NULL;
- }
- else
- {
- memset(hTable->Thelists[i], 0, sizeof(ListNode));
- }
- }
-
- return hTable;
- }
- /*哈希表插入元素,元素为键值对*/
- void Insert(HashTable *HashTable, int key, void *value )
- {
- Element e=NULL, tmp=NULL;
- List L=NULL;
-
- e = Find(HashTable, key);
- if (NULL == e)
- {
- tmp = (Element)malloc(sizeof(ListNode));
-
- if (NULL == tmp)
- {
- printf("malloc error\n");
- return;
- }
-
- L = HashTable->Thelists[Hash(key, HashTable->TableSize)];
- tmp->data = value;
- tmp->key = key;
- tmp->next = L->next;
- L->next = tmp;
- }
- else
- printf("the key already exist\n");
- }
- /*从哈希表中根据键值查找元素*/
- Element Find(HashTable *HashTable, int key)
- {
- int i = 0;
- List L = NULL;
- Element e = NULL;
-
- i = Hash(key, HashTable->TableSize);
- L = HashTable->Thelists[i];
- e = L->next;
-
- while (e != NULL && e->key != key)
- e = e->next;
-
- return e;
- }
- /*哈希表删除元素,元素为键值对*/
- void Delete(HashTable *HashTable, int key )
- {
- Element e=NULL, last=NULL;
- List L=NULL;
- int i = Hash(key, HashTable->TableSize);
- L = HashTable->Thelists[i];
- last = L;
- e = L->next;
- while (e != NULL && e->key != key)
- {
- last = e;
- e = e->next;
- }
-
- if(e)
- { //如果键值对存在
- last->next = e->next;
- delete(e);
- }
- }
- #pragma
-
- #define DEFAULT_SIZE 16
-
- 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;
- #include
- #include
- #include
- #include "hash_table.h"
-
- int Hash(int key, int TableSize)
- {
- return (key % TableSize);
- }
-
- //初始化哈希表
- HashTable* InitHash(int TableSize)
- {
- HashTable* hTable = NULL;
- int i = 0;
-
- hTable = (HashTable*)malloc(sizeof(HashTable));
- if (hTable == NULL)
- {
- printf("分配哈希表失败!");
- return NULL;
- }
-
- if (TableSize < 0)
- {
- TableSize = DEFAULT_SIZE;
- }
- hTable->TableSize = TableSize;
-
- hTable->Thelists = (List *)malloc(sizeof(List) * TableSize);
- if (hTable->Thelists == NULL)
- {
- printf("分配失败!");
- free(hTable);
- return NULL;
- }
-
- for (int i = 0; i < TableSize; i++)
- {
- //if(sizeof(ListNode)
- hTable->Thelists[i] = (ListNode*)malloc(sizeof(ListNode));
-
- if (hTable->Thelists[i] == NULL)
- {
- printf("分配失败!");
- free(hTable->Thelists);
- free(hTable);
-
- return NULL;
- }
- else
- {
- memset(hTable->Thelists[i], 0, sizeof(ListNode));
- }
- }
-
- return hTable;
- }
-
- //从哈希表中根据键值查找元素
- Element Find(HashTable* HashTable, int key)
- {
- int i = Hash(key, HashTable->TableSize);
- List L = NULL;
-
- L= HashTable->Thelists[i];
-
- Element e = NULL;
- e = L->next;
- while (e != NULL && e->key != key)
- {
- e = e->next;
- }
-
- return e;
- }
-
- void Insert(HashTable* HashTable, int key, void* value)
- {
- int i = 0;
- i = Hash(key, HashTable->TableSize);
- List L = NULL;
-
- L = HashTable->Thelists[i];
-
- Element tmp = Find(HashTable, key);
-
- if (!tmp)
- {
- Element e = NULL;
- e = (Element)malloc(sizeof(ListNode));
- if (!e)
- {
- printf("分配失败!");
- return;
- }
-
- e->data = value;
- e->key = key;
- e->next = L->next;
- L->next = e;
- }
- else
- {
- printf("表中有重复键值");
- }
- }
-
- void Delete(HashTable* HashTable, int key)
- {
- int i = Hash(key, HashTable->TableSize);
- List L = NULL;
- L = HashTable->Thelists[i];
-
- Element next = NULL, cur = NULL;
- next = L->next;
- cur = L;
- while (next != NULL && next->key != key)
- {
- cur = next;
- next = next->next;
- }
-
- if (next)
- {
- cur->next = next->next;
- delete(next);
- }
- }
-
- void* Retrieve(Element e)
- {
- return e ? e->data : NULL;
- }
-
- void Destory(HashTable* HashTable)
- {
- int i = 0;
- List L = NULL;
- Element cur = NULL, next = NULL;
-
- for (int i = 0; i < HashTable->TableSize; i++)
- {
- L = HashTable->Thelists[i];
- cur = L->next;
- while (cur != NULL)
- {
- next = cur->next;
- free(cur);
- cur = next;
- }
- free(L);
- }
- free(HashTable->Thelists);
- free(HashTable);
- }
-
- int main(void)
- {
- char *elems[] = { "翠花","小芳","老师" };
- int i = 0;
-
- HashTable* HashTable;
- HashTable = InitHash(31);
- Insert(HashTable, 1, elems[0]);
- Insert(HashTable, 2, elems[1]);
- Insert(HashTable, 3, elems[2]);
- Delete(HashTable, 1);
-
- for (i = 0; i < 4; i++)
- {
- Element e = Find(HashTable, i);
- if (e)
- {
- printf("%s\n", (const char*)Retrieve(e));
- }
- else
- {
- printf("Not found [key:%d]\n", i);
- }
- }
-
- system("pause");
- return 0;
- }