linux内核中的散列表

本文介绍了Linux内核中散列表的原理和实现,包括哈希函数构造方法、处理冲突的链地址法,以及内核散列表的定义、初始化、节点操作(插入、删除、遍历等)。内核使用结构体hlist_head和hlist_node来表示散列表头和节点,并提供了多种操作函数。
摘要由CSDN通过智能技术生成

原理

1、概念

根据设定的哈希函数H(key)和处理冲突的方法将一组关键字映射到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“像”作为记录在表中的存储位置,这种表便称为哈希表或散列表,这一映像过程称为哈希造表或散列,所得存储位置称哈希地址或散列地址。

2、哈希函数的构造方法

1)直接定址法

2)数字分析法

3)平方取中法

4)折叠法

5)除留余数法

6)随机数法

实际工作中需视不同的情况采用不同的哈希函数。通常,考虑的因素有:

1)计算哈希函数所需时间(包括硬件指令的因素)

2)关键字的长度

3)哈希表的大小

4)关键字的分布情况

5)记录的查找频率

3、处理冲突的方法

1)开放定址法

2)再哈希法

3)链地址法

4)建立一个公共缓冲区

4、哈希表的查找

在哈希表上进行查找的过程和哈希造表的过程基本一致。给定K值,根据造表时设定的哈希函数求得哈希地址,若表中此位置上没有记录,则查找不成功;否则比较关键字,若和给定值相等,则查找成功;否则根据造表时设定的处理冲突的方法找“下一地址”,直到哈希表中某个位置为“空”或者表中所填记录的关键字等于给定值时为止。

5、装填因子

哈希表的装填因子定义为:

a = 表中填入的记录数 / 哈希表的长度

a标志哈希表的装满程度。直观地看,a越小,发生冲突的可能性就越小;反之,a越大,表中已填入的记录越多,再填记录时,发生冲突的可能性就越大,则查找时,给定值需与之比较的关键字的个数也就越多。


linux内核中的散列表


在处理记录的冲突时,linux内核使用的方法为链地址法,即将所有关键字为同义词的记录存储在同一线性链表中。

下面分析下,内核针对散列链表实现了哪些操作(所有实现均在源文件inlcude/linux/list.h中)。

1、定义
  1. /* 
  2.  * Double linked lists with a single pointer list head. 
  3.  * Mostly useful for hash tables where the two pointer list head is 
  4.  * too wasteful. 
  5.  * You lose the ability to access the tail in O(1). 
  6.  */  
  7. /* 散列表头结点,即散列链表 */  
  8. struct hlist_head {  
  9.     struct hlist_node *first; /* 指向hlist链表的第一个节点 */  
  10. };  
  11.   
  12. /* 散列表节点 */  
  13. struct hlist_node {  
  14.     /* next: 指向下一个节点 
  15.      * pprev: 指向前一个节点的next域,则*pprev就代表前一个节点的下一个节点的地址(即当前节点) 
  16.      *        当前节点: pprev == 前一个节点: &next 
  17.      *        当前节点: *pprev == 前一个节点: next 
  18.      *        当前节点: **pprev == 前一个节点: *next 
  19.      */  
  20.     struct hlist_node *next, **pprev;  
  21. };  
每一个头节点后面可接若干个节点。
2、声明与初始化
  1. /* 散列表头节点的声明与初始化 */  
  2. #define HLIST_HEAD_INIT { .first = NULL }  
  3. #define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL } /* 静态初始化 */  
  4. #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)  /* 动态初始化 */  
  5.   
  6. /* 散列表节点的初始化 
  7.  * 该函数一般用在删除节点之后对节点的操作中 
  8.  */  
  9. static inline 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值