数据结构--哈希表
1、相关概念
1.哈希算法
将数据通过哈希算法映射成一个键值,存取都在同一位置实现数据的高效存储和查找,并通过这种方式来降低时间复杂度
2.哈希碰撞
多个数据通过算法后得到简直相同的现象叫哈希碰撞
3.哈希表
- 存储结构(桶/槽):一般是一个数组,每个元素被称为一个桶。
- 哈希函数:将键映射到整数,再经过模运算等,得到数组下标,好的哈希函数应尽量使不同键映射到不同的桶
2、哈希表的实现
在该板块中,我将构建一个存放0 - 100 熟知的哈希表,并以此为里说明哈希表的实现方法
1.哈希表的插入
思路:
- 哈希函数:在这里我们用数据除以10得到的余数值区分哈希表的桶
- 定义容量为10的数组指针,数组内指针分别表示每一个桶的地址
- 在目标桶中插入链表节点,节点中存储数据
代码实现:
typedef struct node{ //定义链表节点变量int data; //存贮的数据struct node *pnrext; //下一个节点的地址
}linknode;int *phashtable[10]; //定义数组指针void insert_hashtable(int tmpdata)
{linknode *ptmpnode = NULL; //插入的节点linknode **pptmpnode = NULL; //桶寻址变量int key = 0; //存储余数变量key = tmpdata % 10; //哈希函数for(pptmpnode = &phashtable[key];*pptmpnode != NULL && (*pptmpnode)->data <tmpdata;pptmpnode = &(*pptmpnode)->pnext); //找到要插入的位置ptmpnode = malloc(sizeof(linknode)); //创建节点if(NULL == ptmpnode)prrer("error");ptmpnode->data = tmpdata; //将节点插入目标位置ptmpnode->pnext = *pptmpnode->pnext;*pptmpnode = ptmpnode;
}
2.哈希表的遍历
思路:
利用循环语句访问哈希表每一个桶区的链表
代码实现:
void show_hashtable(void)
{linknode *ptmpnode = NULL;int i = 0;for(i = 0;i < 10;i++){ptmpnode = phashtable[i];while(ptmpnode != NULL){printf("%d ",ptmpnode->data);ptmpnode = ptmpnode->pnext;}}
}
3.哈希表的查找与销毁
思路:与哈希表的遍历思路相同,分别查找或删除每一个同上的链表
代码实现:
/* 哈希表的查找 */linknode *find_hashtable(int tmpdata){ int key = 0;linknode *ptmpnode = NULL;key = tmpdata % 10;ptmpnode = phashtable[key];while (ptmpnode != NULL && ptmpnode->data <= tmpdata){if (ptmpnode->data == tmpdata){return ptmpnode;}ptmpnode = ptmpnode->pnext;}return NULL;}/* 哈希表的销毁 */int destroy_hashtable(void){int i = 0;linknode *ptmpnode = NULL;linknode *pfreenode = NULL;for(i = 0; i < INDEX; i++){ptmpnode = phashtable[i];pfreenode = phashtable[i];while (ptmpnode != NULL){ptmpnode = ptmpnode->pnext;free(pfreenode);pfreenode = ptmpnode;}phashtable[i] = NULL;}return 0;
}