Linux散列表(一)——操作函数
散列表(又名哈希表)仅仅需要一个包含单一指针的链表头。它是双向链表的变体。它不同于双链表——表头和结点使用相同的结构体——散列表对表头和结点有不同的定义。如下:
struct hlist_head {
struct hlist_node *first;
};
struct hlist_node {
struct hlist_node *next, **pprev;
};
散列表的实现一般采用hlist_head数组,每个hlist_head挂一个双向hlist_node链表,大致如下图。其中pprev它指向前一个结点的next指针。
1、初始化
1.1、初始化头
#define HLIST_HEAD_INIT { .first = NULL }
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
1.2、初始化结点
static inline void INIT_HLIST_NODE(struct hlist_node *h)
{
h->next = NULL;
h->pprev = NULL;
}
2、逻辑判断
static inline int hlist_unhashed(const struct hlist_node *h)
{
return !h->pprev;
}
static inline int hlist_empty(const struct hlist_head *h)
{
return !h->first;
}
3、删除结点
3.1、内部API
static inline void __hlist_del(struct hlist_node *n)
{
struct hlist_node *next = n->next;//(1)
struct hlist_node **pprev = n->pprev;//(2)
*pprev = next;//(3)
if (next)
next->pprev = pprev;//(4)
}
3.2、外部API
static inline void hlist_del(struct hlist_node *n)
{
__hlist_del(n);//(1)
n->next = LIST_POISON1;//(2)
n->pprev = LIST_POISON2;//(3)
}
static inline void hlist_del_init(struct hlist_node *n)
{
if (!hlist_unhashed(n)) {
__hlist_del(n);//(1)
INIT_HLIST_NODE(n);//(2)
}
}
4、添加结点
4.1、表头添加结点
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)(0)
{
struct hlist_node *first = h->first;//(1)
n->next = first;//(2)
if (first)
first->pprev = &n->next;//(3)
h->first = n;//(4)
n->pprev = &h->first;//(5)
}
在此基础上再次插入一个结点
4.2、指定结点之前添加结点
/* next must be != NULL */
static inline void hlist_add_before(struct hlist_node *n,
struct hlist_node *next)//(0)
{
n->pprev = next->pprev;//(1)
n->next = next;//(2)
next->pprev = &n->next;//(3)
*(n->pprev) = n;//(4)
}
4.3、指定结点之后添加结点
static inline void hlist_add_after(struct hlist_node *n,
struct hlist_node *next)//(0)
{
next->next = n->next;//(1)
n->next = next;//(2)
next->pprev = &n->next;//(3) if(next->next)
next->next->pprev = &next->next;//(4)
}
/* after that we'll appear to be on some hlist and hlist_del will work */
static inline void hlist_add_fake(struct hlist_node *n)
{
n->pprev = &n->next;
}
5、移动散列表
/*
* Move a list from one list head to another. Fixup the pprev
* reference of the first entry if it exists.
*/
static inline void hlist_move_list(struct hlist_head *old,
struct hlist_head *new)
{
new->first = old->first;//(1)
if (new->first)
new->first->pprev = &new->first;//(2)
old->first = NULL;//(3)
}
Linux散列表(一)——操作函数的更多相关文章
- Linux散列表(二)——宏
散列表宏承接了双向链表宏的风范,好使好用!务必区分“结点”和“元素”!双链表宏博文中已经提及,这里不赘述! 1.获取元素(结构体)基址 #define hlist_entry(ptr, type, m ...
- python字符串 列表 元组 字典相关操作函数总结
1.字符串操作函数 find 在字符串中查找子串,找到首次出现的位置,返回下标,找不到返回-1 rfind 从右边查找 join 连接字符串数组 replace 用指定内容替换指定内容,可以指定次数 ...
- VC散列表
vc下有2个版本的散列表类,hash_map和unordered_map,hash_map位于stdext命名空间,unordered_map在std命名空间(vs2008及其之后的版本可用),官方推 ...
- 散列表Java实现
package 散列表; import java.util.Scanner; public class HashSearch { public static int data[] = {69,65,9 ...
- 10-10Linux的文件操作函数以及所需头文件
Linux的基本文件操作函数 Linux通过相应的对文件的IO函数来实现对文件的操作,这些函数通常被称作"不带缓冲的IO",这是因为他们都是通过调用Linux的内核调用来实 ...
- linux内核的双链表list_head、散列表hlist_head
一.双链表list_head 1.基本概念 linux内核提供的标准链表可用于将任何类型的数据结构彼此链接起来. 不是数据内嵌到链表中,而是把链表内嵌到数据对象中. 即:加入链表的数据结构必须包含一个 ...
- python对redis的常用操作 上 (对列表、字符串、散列结构操作)
这里的一切讨论均基于python的redis-py库. 安装使用: pip install redis 然后去获取一个redis客户端: redis_conn = redis.Redis(host=R ...
- Python 散列表查询_进入<哈希函数>为结界的世界
1. 前言 哈希表或称为散列表,是一种常见的.使用频率非常高的数据存储方案. 哈希表属于抽象数据结构,需要开发者按哈希表数据结构的存储要求进行 API 定制,对于大部分高级语言而言,都会提供已经实现好 ...
- [Linux] Linux进程PID散列表
linux系统中每个进程由一个进程id标识,在内核中对应一个task_struct结构的进程描述符,系统中所有进程的task_struct通过链表链接在一起,在内核中,经常需要通过进程id来获取进程描 ...
随机推荐
- node http.request请求
var http = require('http'); var querystring = require('querystring'); var path = '/cricket/getRecord ...
- LA 6474 Drop Zone (最小割)
题目链接 要添最少的挡板使所有的'D'不存在到达网格外的路径. 以每个格子向四个方向中可以到达的格子连容量为1的边, 从源点向所有'D' 连容量为4的边,网格外的点向汇点连一条容量为4的边. 答案就是 ...
- 【HDU4010】【LCT】Query on The Trees
Problem Description We have met so many problems on the tree, so today we will have a query problem ...
- 使用require.js时,解决AMD封装jquery1.4.1的问题。
require.config({ baseUrl: "js/", paths: { "jquery": "jquery-1.4.1.min" ...
- Bootstrap_表单_图像
在Bootstrap框架中对于图像的样式风格提供以下几种风格: 1.img-responsive:响应式图片,主要针对于响应式设计2.img-rounded:圆角图片3.img-circle:圆形图片 ...
- 去除后台ckeditor的style="...."的样式
.cnt_text .text img {/*width :auto !important;*/height :auto !important; max-width:660px;} 高度自适应,高度让 ...
- JS设置Cookie,及COOKIE的限制
在Javascript脚本里,一个cookie 实际就是一个字符串属性.当你读取cookie的值时,就得到一个字符串,里面当前WEB页使用的所有cookies的名称和值.每个cookie除了 name ...
- PHP常用函数和常量
PHP常用系统常量 __FILE__ 文件的完整路径和文件名.如果用在被包含文件中,则返回被包含的文件名.自 PHP 4.0.2 起,总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在 ...
- mysql oracle 删除外键约束
mysql alter table xxx drop foreign key xxx cascade; oracle alter table drop constraint xxxxx cascade ...
- 初始化rails上的compass项目
compass以外还有一个很实用的scss模块, _media-queries.scss 通过终端下载 curl -O https://raw.github.com/paranoida/sass-me ...