第六章:内核数据结构

6.1链表
链表表示一种存放和操作的可变数据元素的数据结构。
链表与静态数组不同的是它包含的元素是动态创建并且插入链表的,在编译时不必知道具体需要多少个元素。
另外链表中每个元素的创建时间各不相同,所以它们在内存中无需占用连续的空间。
链表中每个元素都包含指向下一元素的指针,当有新元素加入链表时,可以简单的调整指向下一节点的指针就可以了。
 
6.1.2环形链表
通常链表中最后一个元素不在指向下一个元素,所以链表结尾元素的下一指针为NULL,以此表示它是链表的最后一个元素。
但是有些链表中,末尾元素并不指向特殊值,相反,它指回链表的首元素,这种收尾相连的链表叫环形链表。
因为环形链表提供了最大的灵活性,所以Linux内核的标准链表是环形链表。
 
6.2队列
任何操作系统内核中都少不了一种编程模型:生产者和消费者。该模型可以使用队列来时实现。
消费者获得数据的顺序与生产者推入队列的顺序一致。
队列时FIFO,先进先出。
Linux内核通用队列实现称为Kfifo。Kfifo对象维护了两个偏移量:入口偏移和出口偏移。入口偏移时指向下一次入队的位置。出口偏移是指向下一次出队的位置。
 
6.3映射
一个映射,也常称为关联数组,其实是一个由唯一键组成的集合,而每个键必然关联一个特定的值,映射至少包含三个操作:add、remove、Look。
虽然散列表时一种映射,但并非所有的映射都需要通过散列表实现。除了散列表外,映射也可以通过自平衡二叉搜索树存储数据。
通过散列表实现的映射可以提供更好的平均的渐进复杂度。
二叉搜索树可以在最坏的情况下有更好的表现。
二叉搜索树满足顺序保障,这将给用户的按序遍历带来很好的性能。
二叉搜索树最后一个优势是它不需要散列函数,需要的键类型只要可以定义<=操作算子便可以。
 
6.4二叉树
树是一种能提供分层的树型结构的特定数据结构。
一个二叉树是每个节点最多只有两个出边的树。
一个二叉搜索树是一个节点有序的二叉树,其顺序通常遵守以下规则:
根的左分支节点值都小于根节点值
右分支节点值都大于根节点值
所有的子树也都是二叉搜索树。
根据以上规则,在树种搜索一个指定值或者按顺序遍历树相当快。
 
一个平衡二叉搜索树是一个所有节点深度差不超过1的二叉搜索树。
一个自平衡二叉搜索树是指其操作都试图维持平衡的二叉搜索树。
红黑树是一种自平衡二叉搜索树,Linux主要的平衡二叉树数据结构就是红黑树。
红黑树具有以下规则:
所有节点要么是黑色,或者是红色
叶子节点都是黑色
叶子节点不包含数据
所有非叶子节点都有两个子节点
如果一个节点时红色,则它的子节点一定是黑色
在一个节点到子节点的路径中,如果总是包含相同数目的黑色节点,则其路径相比其他路径是最短的。
根据以上条件,可以保证最深的叶子节点深度不会大于两倍的最浅叶子节点的深度,所以红黑树是半平衡的。
 
6.5数据结构以及选择
当你对数据结构的操作主要是遍历,就使用链表,没有数据结构可以可以提供比线性算法复杂度更好的算法遍历元素。
如果你的代码符合生产者-消费者模型,则使用队列。
如果你需要存储大量数据,并且检索迅速,则使用红黑树最好。
 
6.6时间复杂度
1 衡量
logN 对数
n 线性
n的2次方 平方
n的3次方 立方
2的N次方 指数
n! 阶乘

猜你喜欢

转载自www.cnblogs.com/use-D/p/10575807.html