2013 年 5 月 22 日 by sciencefans
今天看Harvard的CS50第13Lesson,视频最后教授给大家布置了一个作业,要求在复杂度小于O(Log2(N))的时间内查找给定数据,当然数据的读入不计入总时间。于是就兴高采烈地翘了物理课Google了一下hash,结果一泡就是一下午。。。
Hash是一个介于数组和链表之间的一种查找结构,它结合了数组的快速定位优点和链表的储存于堆中大小限制低以及收放自如的优点。
Hash表是一个类似电话薄的结构,先将元素分类,再在各类中顺序查找。所以复杂度取决于类的划分。划分的好的话可以达到常数复杂度的效果,划分的不好会变成线性搜索。一般采用动态划分。
下面是一个简单的Hash举例。
a)定义hash表和基本数据节点
1 typedef struct _NODE 2 { 3 int data; 4 struct _NODE* next; 5 }NODE; 6 7 typedef struct _HASH_TABLE 8 { 9 NODE* value[10]; 10 }HASH_TABLE;
b)创建hash表
1 HASH_TABLE* create_hash_table() 2 { 3 HASH_TABLE* pHashTbl = (HASH_TABLE*)malloc(sizeof(HASH_TABLE)); 4 memset(pHashTbl, 0, sizeof(HASH_TABLE)); 5 return pHashTbl; 6 }
c)在hash表当中寻找数据
1 NODE* find_data_in_hash(HASH_TABLE* pHashTbl, int data) 2 { 3 NODE* pNode; 4 if(NULL == pHashTbl) 5 return NULL; 6 7 if(NULL == (pNode = pHashTbl->value[data % 10])) 8 return NULL; 9 10 while(pNode){ 11 if(data == pNode->data) 12 return pNode; 13 pNode = pNode->next; 14 } 15 return NULL; 16 }
d)在hash表当中插入数据
1 STATUS insert_data_into_hash(HASH_TABLE* pHashTbl, int data) 2 { 3 NODE* pNode; 4 if(NULL == pHashTbl) 5 return FALSE; 6 7 if(NULL == pHashTbl->value[data % 10]){ 8 pNode = (NODE*)malloc(sizeof(NODE)); 9 memset(pNode, 0, sizeof(NODE)); 10 pNode->data = data; 11 pHashTbl->value[data % 10] = pNode; 12 return TRUE; 13 } 14 15 if(NULL != find_data_in_hash(pHashTbl, data)) 16 return FALSE; 17 18 pNode = pHashTbl->value[data % 10]; 19 while(NULL != pNode->next) 20 pNode = pNode->next; 21 22 pNode->next = (NODE*)malloc(sizeof(NODE)); 23 memset(pNode->next, 0, sizeof(NODE)); 24 pNode->next->data = data; 25 return TRUE; 26 }
e)从hash表中删除数据
1 STATUS delete_data_from_hash(HASH_TABLE* pHashTbl, int data) 2 { 3 NODE* pHead; 4 NODE* pNode; 5 if(NULL == pHashTbl || NULL == pHashTbl->value[data % 10]) 6 return FALSE; 7 8 if(NULL == (pNode = find_data_in_hash(pHashTbl, data))) 9 return FALSE; 10 11 if(pNode == pHashTbl->value[data % 10]){ 12 pHashTbl->value[data % 10] = pNode->next; 13 } 14 else 15 { 16 pHead = pHashTbl->value[data % 10]; 17 while(pNode != pHead ->next) 18 pHead = pHead->next; 19 pHead->next = pNode->next; 20 } 21 22 free(pNode); 23 return TRUE; 24 }