数据结构-哈希表(散列表)
1.基本概念
哈希表(散列表):提高数据的查找效率
哈希存储:将要存储的数据的关键字和存储位置之间,建立起对应的关系,
这个关系称之为哈希函数。存储数据时,通过对应的哈希函数可以将数据映射到指定的存储位置;查找时,仍可通过该函数找到数据的存储位置。
哈希冲突/哈希矛盾:
key1 != key2
f(key1) == f(key2)
处理哈希冲突的方法:
1)开放地址法:
思想:当发生哈希冲突时,通过探测序列在哈希表中寻找下一个可用的空槽位,直到找到合适的位置插入元素。所有元素都存储在哈希表本身中(无额外数据结构)。
2)链地址法
思想:将哈希表的每个槽位作为链表头节点,冲突的元素直接插入对应槽位的链表中。哈希表本身只存储链表的引用。
2.基本操作
(1)哈希函数
int hash_function(char key)
{if (key >= 'a' && key <= 'z'){return key-'a';}else if (key >= 'A' && key <= 'Z'){return key-'A';}else{return HASH_TABLE_MAX_SIZE-1;}
}
(2)创建一个哈希表
HSNode_t *hash_table[HASH_TABLE_MAX_SIZE] = {NULL};
(3)插入(有序)
int insert_hash_table(HSNode_t **hash_table, Data_type_t data)
{int addr = hash_function(data.name[0]);//申请结点保存数据//头插//hash_table[addr]; //---->pheadHSNode_t *pnode = malloc(sizeof(HSNode_t));if (NULL == pnode){printf("malloc error\n");return -1;}pnode->data = data;pnode->pnext = NULL;if (NULL == hash_table[addr]){hash_table[addr] = pnode;}else{if (strcmp(pnode->data.name, hash_table[addr]->data.name) <= 0){pnode->pnext = hash_table[addr];hash_table[addr] = pnode;}else{HSNode_t *p = hash_table[addr];while (p->pnext != NULL && (p->pnext->data.name, pnode->data.name) < 0){p = p->pnext;}pnode->pnext = p->pnext;p->pnext = pnode;}}return 0;
}
(4)遍历
void hash_for_each(HSNode_t **hash_table)
{for (int i = 0; i < HASH_TABLE_MAX_SIZE; ++i){HSNode_t *ptmp = hash_table[i];while (ptmp){printf("%s : %s\n", ptmp->data.name, ptmp->data.tel);ptmp = ptmp->pnext;}printf("\n");}
}
(5)查找
HSNode_t *find_hash_table(HSNode_t **hash_table, char *name)
{int addr = hash_function(name[0]);HSNode_t *ptmp = hash_table[addr];while (ptmp){if (0 == strncmp(ptmp->data.name, name, strlen(name))){return ptmp;}ptmp = ptmp->pnext;}return NULL;
}
(6)销毁
void destroy_hash_table(HSNode_t **hash_table)
{for (int i = 0;i < HASH_TABLE_MAX_SIZE; i++){HSNode_t *pdel = hash_table[i];while (hash_table[i] != NULL){hash_table[i] = pdel->pnext;free(pdel);pdel = hash_table[i];}}
}