这些常用算法,你知道它们都被用在哪里吗(上)
Posted 技术风向标
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了这些常用算法,你知道它们都被用在哪里吗(上)相关的知识,希望对你有一定的参考价值。
上周我们推送了一篇文章《经典算法排行榜》(回复数字5阅读),文中列举了32个常用的算法。但只把这些算法列出来,似乎还是没什么存在感,或者说没有直观感受。
Stackexchange上曾经有这样一个问题,提问者希望有人能够列举一些目前软件、硬件中正在使用的算法的实际案例来证明算法的重要性,他还提出了几点要求:
使用这些算法的软件或者硬件应该是被广泛应用的;
在经典的本科生或者博士的课程中应该教过这些算法或者数据结构;
看看大家是怎么说的。
链表、双向链表和无锁链表
B+ 树,代码中的注释将会告诉你一些教科书中不能学到的内容:
这是一个简单的B+树实现,我写它的目的是作为练习,并以此了解B+树的工作原理。结果该实现发挥了它的实用价值。
...
一个不经常在教科书中提及的技巧:最小值应该放在右侧,而不是左侧。一个节点内所有被使用的槽位应该在左侧,没有使用的节点应该为NUL,大部分的操作只遍历一次所有的槽位,在第一个NUL处终止。
带权重的有序列表用于互斥锁、驱动等;
红黑树用于调度、虚拟内存管理、跟踪文件描述符和目录条目等;
区间树
Radix树,用于内存管理、NFS相关查找和网络相关的功能;
radix树的一个常见的用法是保存页面结构体的指针;
优先级堆,文字上的描述,主要是在教科书中实现,用于control group系统;
包含指针的只允许简单插入的静态大小优先级堆,基于CLR(算法导论)第七章
哈希函数,引用Knuth和他的一篇论文:
Knuth建议选择与机器字长所能表达的最大整数约成黄金比例的素数来做乘法散列,Chuck Lever 证实了这个技术的有效性;
http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
这些选择的素数是位稀疏的,也就是说对他们的操作可以使用位移和加法来替换机器中很慢的乘法操作;
哈希表,用于实现索引节点、文件系统完整性检查等;
位数组,用于处理flags、中断等,在Knuth第四卷中有对其特性的描述;
Semaphores 和 spin locks
二叉树搜索用于中断处理、登记缓存查找等;
使用B-树进行二叉树查找;
深度优先搜索和他的变体被应用于目录配置;
在命名空间树中执行一个修改过的深度优先算法,开始(和终止于)start_handle所确定的节点。当与参数匹配的节点被发现以后,回调函数将会被调用。如果回调函数返回一个非空的值,搜索将会立即终止,这个值将会回传给调用函数;
广度优先搜索用于在运行时检查锁的正确性;
链表上的合并排序用于垃圾回收、文件系统管理等;
在某个驱动程序的库函数里,冒泡排序居然也被实现了
Knuth-Morris-Pratt 字符串匹配;
Knuth、Morris和 Pratt [1]实现了一个线性时间复杂度字符串匹配算法。该算法完全规避了对转换函数DELTA的显式计算。其匹配时间为O(n)(其中n是文本长度),只使用一个辅助函数PI[1...m](其中m是模式的长度),模式的预处理时间是O(m)。PI这个数组允许DELTA函数在需要时能迅速运行。大体上,对任意状态q=0,1,...,m和任意SIGMA中的字符"a",PI["q"]保存了独立于"a"的信息,并用于计算DELTA("q", "a")。由于PI这个数组只包含m个条目,而DELTA包含O(m|SIGMA|)个条目,我们通过计算PI进而在预处理时间保存|SIGMA|的系数,而非计算DELTA。
[1] Cormen, Leiserson, Rivest, Stein Introdcution to Algorithms, 2nd Edition, MIT Press
[2] See finite automation theory
Boyer-Moore模式匹配,如下是引用和对其他算法的使用建议;
Boyer-Moore字符串匹配算法:
[1] A Fast String Searching Algorithm, R.S. Boyer and Moore. Communications of the Association for Computing Machinery, 20(10), 1977, pp. 762-772.http://www.cs.utexas.edu/users/moore/publications/fstrpos.pdf
[2] Handbook of Exact String Matching Algorithms, Thierry Lecroq, 2004 http://www-igm.univ-mlv.fr/~lecroq/string/string.pdf
注意:由于Boyer-Moore(BM)自右向左做匹配,有一种可能性是一个匹配分布在不同的块中,这种情况下是不能找到任何匹配的。
如果你想确保这样的事情不会发生,使用Knuth-Pratt-Morris(KMP)算法来替代。也就是说,根据你的设置选择合适的字符串查找算法。
如果你使用文本搜索架构来过滤、网络入侵检测(NIDS)或者任何安全为目的,那么选择KMP。如果你关乎性能,比如你在分类数据包,并应用服务质量(QoS)策略,并且你不介意可能需要在分布在多个片段中匹配,然后就选择BM。
伸展树
此树会被分配策略参数化,这个策略负责在C的自由存储空间和区域中分配列表,参见zone.h
Demo中使用了Voronoi图
基于Bresenham算法的标签管理
同时,代码中还包含了一些第三方的算法和数据结构,例如:
二叉树
红黑树
AVL树
用于压缩的Rabin-Karp字符串匹配
计算自动机的后缀
苹果实现的布隆过滤器
布氏算法
其它还有很多,比如用在加密算法里的,编译器中的,且听小标下回分解。
以上是关于这些常用算法,你知道它们都被用在哪里吗(上)的主要内容,如果未能解决你的问题,请参考以下文章