http://vinllen.com/linuxnei-he-zhong-de-shu-ju-jie-gou/

https://zhuanlan.zhihu.com/p/58087261

https://blog.csdn.net/wenqian1991/article/details/44515713

https://blog.csdn.net/ace_an/article/details/53813242

Linux中最重要最常用如下四种:

LIST:链表 <linux/list.h>
Linux内核的标准链表就是采用“环形、双向”链表形式实现
沿着链表移动智能是线性移动
需要随机访问的数据,一般不使用链表
链表存放数据的理想情况是:需要遍历所有数据、或者需要动态加入/删除数据
有时首元素会用一个特殊的指针表示,称为“头指针”,可以方便的找到链表的“起始端”
Linux内核实现特殊性:不是将数据结构塞入链表,而是将链表结点塞入数据结构
Linux内核链表操作函数的复杂度都是O(1),而不管链表中元素数目的多少
list_add\__list_add
list_add_tail\__list_add_tail
list_del\__list_del
list_del_init\__list_del_init
list_move\__list_move
list_move_tail\__list_move_tail
list_empty\__list_empty
list_entry\__list_entry
list_splice\__list_splice
list_splice_init\__list_splice_init
Linux内核遍历链表的复杂度是O(n),n是链表元素数目
list_for_each
list_for_each_entry
list_for_each_entry_reverse 反向遍历链表,有二原因:①当反向遍历性能好时;②当遍历顺序很重要时;
list_for_each_entry_safe 该函数允许在遍历链表循环体中删除元素,普通遍历函数不允许这样做
list_for_each_entry_safe_reverse
链表操作函数分为外部函数、内部函数,函数同名,只差双下划线__,内部函数用prev、next参数

FIFO:队列 <linux/kfifo.h>
Linux内核通用队列实现称为kfifo,实现在文件kernel/kfifo.c中
维护两个偏移量:
入口偏移(下一次入队时位置)>=出口偏移(下一次出队时位置);
入口偏移==出口偏移,说明队列空了;
入口偏移==队列长度,说明队列重置前不能再有入队操作;
提供两个主要操作:
入队enqueue(copy数据到队列入口偏移位置)
出队dequeue(从队列出口偏移copy数据)
队列操作:
kfifo_alloc 动态创建、初始化 (size需是2的n次幂)
kfifo_init 动态创建、初始化,但使用已分配内存 (size同上)
DECLARE_KFIFO/INIT_KFIFO 静态声明,不常用(size同上)
kfifo_in   入队
kfifo_out   出队
kfifo_out_peek   不出队,只返回数据
kfifo_size   队列总体空间(长度)
kfifo_len   队列已用空间
kfifo_avail   队列剩余空间
kfifo_is_empty   判定队列空
kfifo_is_full   判定队列满
kfifo_reset   重置队列(抛弃所有元素)
kfifo_free   释放kfifo_alloc创建的队列

映射:
称为关联数组,由“键<==>值”对儿组成的集合; 
“键”是唯一的,“值”关联到键;
映射操作:
Add (key, value)   增加
Remove (key)   删除
Value = Lookup (key)   查找
Allocate   插入键值对,产生UID
Linux内核提供了简单、有效的映射数据结构。但是它并非一个通用的映射;
Linux内核提供它的目标是:映射一个唯一的标识数(UID)到一个指针; (因此并不适合其它场景)
idr数据结构:用于映射用户空间的UID
idr_init   初始化静态/动态分配的idr
...

二叉树:
树,是一个能提供分层的“树”型数据结构的特定数据结构;
树,是一个无环、连接的有向图;
树,任何一个节点具有0~n个出边,1个入边;
节点深度,是从根节点起到达该节点止一共需要经过的父节点数目;
树的高度,是叶子节点的深度;
二叉树,任何一个节点最多有2个出边的树,即只能有0、1、2个出边;
BST:二叉搜索树
规则1:根左分支节点值 < 根节点值
规则2:根右分支节点值 > 根节点值
规则3:所有子树都是二叉搜索树
前序遍历:根节点->左子树->右子树
中序遍历:左子树->根节点->右子树
后序遍历:左子树->右子树->根节点
在树中搜索给定值、按序遍历都相当快捷;中序遍历二叉搜索树时会按照节点值从小到大的顺序排序;
自平衡二叉搜索树
平衡二叉搜索树:所有叶子节点深度差值都不超过1的二叉搜索树
自平衡二叉搜索树:操作都试图维持平衡(半平衡)的二叉搜索树
红黑树
是一种“自平衡二叉搜索树”
是Linux主要的平衡二叉搜索树
具有特殊的着色属性(或红色、或黑色)
能维持半平衡结构,其6属性:
属性1:所有节点要么着红色、要么着黑色
属性2:叶子节点都是黑色
属性3:叶子节点不包含数据
属性4:非叶子节点都有2个子节点
属性5:如果节点是红色,则它子节点都是黑色
属性6:一个节点到该节点的叶子节点的所有路径中,总是包含相同数目的黑色节点;
上述属性确保:
一个红色节点不能是其它红色节点的子节点(或者父节点),即两个红色节点不能相连;
从树的任何一个节点到其叶子节点的路径都具有相同数目的黑色节点;即最长路径是红黑交替路径,最短路径是全黑路径;
所以,最深叶子节点深度,不会大于2倍最浅叶子节点深度; 红黑树总是半平衡的;
rbtree: <linux/rbtree.h>
Linux实现的红黑树
实现在lib/rbtree.c中
插入效率和树中节点数目呈现对数关系;(即:时间复杂度与节点数目是对数关系)
根节点由数据结构rb_root描述,创建新红黑树,需要分配新的rb_root结构并初始化为RB_ROOT
其它节点由数据结构rb_node描述
未提供搜索和插入操作函数,需要由用户自己实现(可以使用rbtree提供的辅助函数,但要实现比较操作算子)

其它较少用的:
radixtree:基数树

数据结构的选择:
原则一:遍历操作为主时,优先考虑链表;(没有数据结构能提供比线性算法复杂度更好的算法去遍历元素)
原则二:排除性能因素,当需要相对较少数据项时,优先考虑链表;
原则三:当需要与其它选择链表的代码交互时,优先考虑链表;
原则四:需要大小不明的数据集合,优先选择链表;
原则五:代码架构复合"生产者/消费者"模式,优先选择队列;
原则六:当需要一个定长的缓冲,选择队列;
原则七:如果需要映射一个UID到一个对象,选择映射;
原则八:如果需要存储大量数据,并且快速检索,选择红黑树;

转载于:https://www.cnblogs.com/clemente/p/10887589.html

linux内核中的数据结构相关推荐

  1. Linux 内核中的数据结构:双链表,基数树,位图

    Linux 内核中的数据结构 rtoax 2021年3月 1. 双向链表 Linux 内核自己实现了双向链表,可以在 include/linux/list.h 找到定义.我们将会从双向链表数据结构开始 ...

  2. 计算机原理-操作系统- 转发 微博 Qzone 微信 Linux内核中的数据结构和算法

    原创 底层软件架构 2019-07-12 22:40:12 Linux内核(源代码的链接在github) 1.链表.双向链表.无锁链表. 2.B+ 树,这是一些你无法在教科书上找到的说明. 一个相对简 ...

  3. 简单谈一点linux内核中套接字的bind机制--数据结构以及端口确定

    众所周知,创建一个套接字可以bind到一个特定的ip地址和端口,实际上套接字这一概念代表了TCP/IP协议栈的应用层标识,协议栈中的应用层就是通过一个ip地址和一个端口号标识的,当然这仅仅是对于TCP ...

  4. Linux内核分析--内核中的数据结构双向链表续【转】

    在解释完内核中的链表基本知识以后,下面解释链表的重要接口操作: 1. 声明和初始化 实际上Linux只定义了链表节点,并没有专门定义链表头,那么一个链表结构是如何建立起来的呢?让我们来看看LIST_H ...

  5. linux内核arc4算法,linux内核中与进程相关的数据结构(基于linux-mainline-rc4)

    1.进程描述符 struct task_struct { volatile long state; ....... struct list_head tasks; ....... struct mm_ ...

  6. Linux内核中的算法和数据结构

    算法和数据结构纷繁复杂,但是对于Linux Kernel开发人员来说重点了解Linux内核中使用到的算法和数据结构很有必要. 在一个国外问答平台stackexchange.com的Theoretica ...

  7. Linux 内核中的 Device Mapper 机制

    本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...

  8. 如何放出Linux内核中的链表大招

    前言 上回,我们说到Linux内核中max()宏的终极奥义,Linux内核链表也不甘示弱,那么接下来,让我们看看Linux内核中的链表大招. 如何放出Linux内核中的链表大招 前言 一.链表简介 ( ...

  9. Linux中文件描述符1,linux内核中的文件描述符(一)--基础知识简介

    原标题:linux内核中的文件描述符(一)--基础知识简介 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blo ...

最新文章

  1. 力邀安卓为鸿蒙效力,期末阅读题答题秘籍2
  2. 2020年人工神经网络第二次作业-参考答案第四题
  3. One Day-XML:XPath
  4. Linux系统之高级用户组和权限管理
  5. 读未来产品的设计(1)
  6. 在互联网行业Java程序员的工资标准是多少呢?
  7. 2012-05-04 12:58 eclipse老是building workspace及自动更新问题,eclipse加速
  8. php父类继承子类_php有多态吗 多态都有什么好处?理解好多态往往能事半功倍...
  9. 可汗学院统计学笔记 42-81集
  10. wampserver服务器无法启动(图标颜色不对)
  11. Sublime搭建Java程序运行环境
  12. Mac如何设置文本中的单双引号样式?
  13. CS224N笔记——RNN和语言模型
  14. linux 抓包tcp
  15. Axure RP 9 原型图的绘制及交互
  16. 经验模态分解python_EMD经验模态分解
  17. Servlet基础:容器
  18. 基于Tableau的疫情数据可视化看板
  19. drupal7 分页
  20. 如何删除复制文字产生的word回车换行符

热门文章

  1. ASP.NET Web 项目文件类型
  2. (一).NET SubSonic2.0 的配置
  3. jggrid应用于asp.net
  4. 金山毒霸2007终身升级版V8.0正式上线(2006.12.30最新版)
  5. tddebug怎么读取asm文件_如何利用 ASM 实现既有方法的增强?
  6. pte模拟考试_【PTE懒人攻略】如何在7天内通过PTE考试
  7. Codeforces 463E Caisa and Tree
  8. TP5 自带分页类的传参
  9. 2018.06.28 与或(线段树)
  10. CSS高度塌陷问题-清除浮动