关于语言不可知论:什么是鲜为人知但有用的数据结构?

What are the lesser known but useful data structures?

周围有些数据结构确实有用,但大多数程序员都不知道。他们是谁?

每个人都知道链表、二叉树和散列,但是例如跳过列表和bloom过滤器呢?我想知道更多不太常见的数据结构,但值得知道,因为它们依赖于伟大的思想,丰富了程序员的工具箱。

PS:我还对跳舞链接等技术感兴趣,这些技术巧妙地利用了通用数据结构的属性。

编辑:请尝试更详细地包含到描述数据结构的页面的链接。另外,尝试添加几个词来说明为什么数据结构很酷(如jonas k?Lker已经指出了)。另外,尝试为每个答案提供一个数据结构。这将允许更好的数据结构仅根据其投票数浮到顶部。


尝试,也被称为前缀树或临界位树,已经存在40多年,但仍然相对未知。尝试的一个非常酷的用法描述在"垃圾桶-一个动态的lc trie和hash数据结构",它将trie和hash函数结合在一起。


Bloom filter of M比特位阵列:在initially to 0,集。P></

You Run to add an item的哈希函数,它通过K K指数会给你,那么你在哪集数组1。P></

to check if an item is the茶具,K指数计算和check if they are to 1的集。P></

of some of this),给positives错误概率(根据维基百科是about 0.61公尺(N M / N)where is the number of inserted items)。negatives are not possible的假。P></

an item is除尘是不可能的,但你可以实施"订单计数布鲁姆过滤器阵列模式,ints公社和增量/减量)。P></


绳:这是便宜的,allows字符串子串中,前置换,appends insertions布尔。我真的只有使用*盎司,但不会sufficed其他结构。字符串和正则arrays预备什么只是让我们needed to for太’给你,和reversing everthing was out of the question。P></


跳过名单是漂亮整洁。P></

Wikipedia
A skip list is a probabilistic data structure, based on multiple parallel, sorted linked lists, with efficiency comparable to a binary search tree (order log n average time for most operations).

they can be used as to an替代平衡树(平衡的概率比使用"严格执法(平衡)。他们是易实施"订单和更快比说,在红-黑树。我认为他们中的每一programmers toolchest should be good。P></

如果你想深入的安在to get to在这里介绍的是在跳跃列表链接到视频mit' of them to s介绍讲座在线算法。P></

here is also,Java Applet visually demonstrating跳过列表。P></


空间索引,特别是R树和Kd树,能够有效地存储空间数据。它们适用于地理地图坐标数据和超大规模集成电路的位置和路由算法,有时也适用于最近邻搜索。

位数组紧凑地存储单个位,并允许快速的位操作。


Zippers——数据结构的派生,它将结构修改为具有"光标"的自然概念——当前位置。这些功能非常有用,因为它们可以保证指标不会超出限制——例如,在xmonad窗口管理器中,使用它们来跟踪哪个窗口已经聚焦。

令人惊讶的是,您可以通过将微积分技术应用于原始数据结构的类型来获得它们!


这里有几个:

  • 后缀尝试。对于几乎所有类型的字符串搜索都很有用(http://en.wikipedia.org/wiki/suffix_trie功能)。另请参见后缀数组;它们不如后缀树快,而是小得多。

  • 展开树木(如上所述)。他们冷静的原因有三个方面:

    • 它们很小:您只需要像在任何二进制树中那样的左右指针(不需要存储节点颜色或大小信息)。
    • 它们(相对而言)很容易实施
    • 它们为整个"测量标准"提供了最佳的分摊复杂性(每个人都知道对数查找时间)。请参见http://en.wikipedia.org/wiki/splay_tree性能_定理
  • 按堆排序的搜索树:在一个树中存储一组(key,prio)对,这样它就成为一个与键相关的搜索树,而按优先级排序的堆。我们可以看到这样一棵树有一个独特的形状(而且它并不总是被完全包装起来并一直放在左边)。使用随机优先级,它会给您预期的O(log n)搜索时间,iirc。

  • 一个小生境是O(1)邻接查询的无向平面图的邻接表。这与其说是一种数据结构,不如说是一种组织现有数据结构的特殊方式。你可以这样做:每个平面图都有一个最多6度的节点。选择这样一个节点,将它的邻居放在它的邻居列表中,将其从图中删除,然后循环使用,直到图为空。当给定一对(u,v)时,在v的邻居列表中查找u,在u的邻居列表中查找v。两者的大小都不超过6,所以这是O(1)。

根据上面的算法,如果u和v是邻居,那么v列表中就不会同时有u和v。如果需要,只需将每个节点丢失的邻居添加到该节点的邻居列表中,但要存储快速查找所需的邻居列表的数量。


我认为标准数据结构的无锁替代方案(即无锁队列、堆栈和列表)被忽视了。随着并发性成为一个更高的优先级,它们变得越来越重要,并且比使用互斥锁或锁处理并发读/写更令人钦佩。

这里有一些链接http://www.cl.cam.ac.uk/research/srg/netos/lock-free/http://www.research.ibm.com/people/m/michael/podc-1996.pdf[链接至pdf]http://www.boyet.com/articles/lockfreestack.html网站

Mike Acton的博客(经常是挑衅性的)有一些关于无锁设计和方法的优秀文章。


我想我是条不相交集nifty漂亮当你need to for cases of items into distinct分帮会员集合和查询。好的联盟和find操作执行,结果是在amortized成本effectively常数(S)ackermnan'逆函数,如果我记得正确的数据结构类)。P></


斐波那契堆

它们被用于一些已知最快的算法(渐进式)中,用于许多与图相关的问题,例如最短路径问题。Dijkstra的算法使用标准的二进制堆在O(e log v)时间内运行;使用fibonacci堆将其改进为O(e+v log v),这对密集图来说是一个巨大的加速。然而,不幸的是,它们有一个很高的常数因子,经常使它们在实践中变得不切实际。


有经验的人熟悉的3D渲染should be with BSP树。这是generally,the method to be by structuring在3D场景的渲染manageable for the knowing坐标和轴承室。P></

Binary space partitioning (BSP) is a
method for recursively subdividing a
space into convex sets by hyperplanes.
This subdivision gives rise to a
representation of the scene by means
of a tree data structure known as a
BSP tree.

In other words, it is a method of
breaking up intricately shaped
polygons into convex sets, or smaller
polygons consisting entirely of
non-reflex angles (angles smaller than
180°). For a more general description
of space partitioning, see space
partitioning.

Originally, this approach was proposed
in 3D computer graphics to increase
the rendering efficiency. Some other
applications include performing
geometrical operations with shapes
(constructive solid geometry) in CAD,
collision detection in robotics and 3D
computer games, and other computer
applications that involve handling of
complex spatial scenes.


哈夫曼树-用于压缩。


看看手指树,特别是如果您是前面提到的纯功能数据结构的爱好者。它们是持久序列的函数表示,支持在摊余常量时间内访问端点,并以较小片段的大小以时间对数形式连接和拆分。

根据原文:

Our functional 2-3 finger trees are an instance of a general design technique in- troduced by Okasaki (1998), called implicit recursive slowdown. We have already noted that these trees are an extension of his implicit deque structure, replacing pairs with 2-3 nodes to provide the flexibility required for efficient concatenation and splitting.

手指树可以用一个单倍体参数化,使用不同的单倍体将导致树的不同行为。这可以让手指树模拟其他数据结构。


圆形或环形缓冲区-用于流式传输,以及其他功能。


我很惊讶没有人提到过梅克尔树(即哈希树)。

在许多情况下(P2P程序、数字签名),当您只有部分文件可供使用时,您希望验证整个文件的哈希。


Van Emde-Boas trees

我想知道他们为什么很酷是很有用的。一般来说,"为什么"是最重要的问题;)

我的答案是他们给你的O(log log n)字典有1..n键,与使用的键数量无关。就像重复减半给你O(log n),重复的sqrting给你O(log n),这就是veb树中发生的事情。


八字树怎么样?

此外,ChrisOkasaki的纯功能数据结构也浮现在脑海中。


散列表的一个有趣的变种叫做布谷鸟散列。它使用多个哈希函数而不是1来处理哈希冲突。通过从主哈希指定的位置删除旧对象,并将其移动到备用哈希函数指定的位置,可以解决冲突。布谷鸟散列允许更有效地使用内存空间,因为您可以增加您的负载系数高达91%,只有3个散列函数,仍然有良好的访问时间。


最小-最大堆是实现双端优先级队列的堆的变体。它通过对heap属性的简单更改来实现这一点:如果偶数(奇数)级别上的每个元素都小于(大于)所有子级和孙子级,则称树为最小-最大顺序树。级别从1开始编号。

网址:http://internet512.chonbuk.ac.kr/datastructure/heap/img/heap8.jpg


我喜欢缓存遗忘的数据结构。其基本思想是以递归的更小的块来布局树,这样许多不同大小的缓存就可以利用适合它们的块。这就可以有效地使用从RAM中的一级缓存到从磁盘读取的大数据块的各种缓存,而无需了解这些缓存层的具体大小。


偏左的红黑树。2008年,罗伯特·塞奇威克(Robert Sedgewick)发布了一个大大简化的红黑树实现(约一半代码行要实现)。如果您在实现红黑树时遇到过麻烦,请阅读这个变体。

与安德森树非常相似(如果不相同)。


工作窃取队列

用于在多个线程之间分配工作均等的无锁数据结构C/C++中工作窃取队列的实现


由gerth st引导的倾斜二项堆?Ting Brodal和Chris Okasaki:

尽管它们的名字很长,但它们提供了渐进的最优堆操作,即使在函数设置中也是如此。

  • O(1)尺寸,活接头,插入件,最小值
  • O(log n)删除分

注意,union需要O(1)而不是O(log n)的时间,这与数据结构教科书(如leftist heaps)中通常涉及的更知名的堆不同。与斐波那契堆不同的是,这些渐近是最坏的情况,而不是摊销,即使是长期使用!

Haskell中有多个实现。

它们是由brodal和okasaki共同推导出来的,brodal提出了一个具有相同渐近性的命令堆。


球树。只是因为它们能让人咯咯笑。

球树是一种在度量空间中对点进行索引的数据结构。这是一篇关于建造它们的文章。它们通常用于寻找某一点的最近邻点或加速k均值。


  • Kd树是实时光线跟踪中使用的空间数据结构,其缺点是交叉于不同空间的三角形需要裁剪。通常英属维尔京群岛更快,因为它们更轻。
  • mx-cif四叉树,通过将常规四叉树与四叉树边缘的二叉树相结合,存储边界框而不是任意点集。
  • 由于涉及常量,访问时间通常超过O(1)哈希图的层次哈希图。
  • 反向索引,在搜索引擎中非常有名,因为它用于快速检索与不同搜索词相关的文档。

其中大部分(如果不是全部)都记录在NIST算法和数据结构词典中。


不是真正的数据结构;更多的是一种优化动态分配数组的方法,但是Emacs中使用的间隙缓冲区有点酷。


芬威克树。它是一种数据结构,用来计算一个向量中所有元素的和,在两个给定的子索引i和j之间。这是一个平凡的解决方案,因为开始不允许更新一个项(您必须做O(n)工作才能跟上)。

Fenwick树允许您在O(log n)中更新和查询,它的工作方式非常酷和简单。在芬威克的原版文件中解释得很好,这里免费提供:

http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol24/issue3/spe884.pdf

它的父亲RQM树也非常酷:它允许您在向量的两个索引之间保存关于最小元素的信息,并且它还可以在O(logn)更新和查询中工作。我喜欢先教RQM,然后教芬威克树。


范艾德博阿斯树。我甚至有一个C++实现,最多可以达到2 ^ 20个整数。


嵌套集很适合表示关系数据库中的树并对其运行查询。例如,ActiveRecord(RubyonRails的默认ORM)附带了一个非常简单的嵌套集插件,这使得使用树变得简单。


展开的链接列表是链接列表上的变体,它在每个节点中存储多个元素。它可以显著提高缓存性能,同时减少与存储列表元数据(如引用)相关联的内存开销。它与B-树有关。

1
2
3
4
5
record node {
    node next       // reference to next node in list
    int numElements // number of elements in this node, up to maxElements
    array elements  // an array of numElements elements, with space allocated for maxElements elements
}

替罪羊树。普通二叉树的一个典型问题是它们变得不平衡(例如,当键按升序插入时)。

平衡二叉树(也称为AVL树)在每次插入后都会浪费大量的时间来平衡。

红黑树保持平衡,但每个节点需要额外的存储空间。

替罪羊树保持平衡,像红黑树,但不需要任何额外的存储。它们通过在每次插入之后分析树并进行细微的调整来实现这一点。参见http://en.wikipedia.org/wiki/scapegoat-tree。


这是一个非常特定的领域,但是半边缘数据结构非常整洁。它提供了一种迭代多边形网格(面和边)的方法,这在计算机图形学和计算几何中非常有用。


Hinze和Paterson的2-3指状树是一种功能强大的数据结构,具有很强的渐进性,适用于广泛的作战。虽然很复杂,但是它们比命令式结构简单得多,通过前面的kaplan和tarjan通过递归减速实现链接的持久列表。

它们作为一个可分类的deque工作,其中O(1)访问任一端,O(log min(n,m))附加,并提供O(log min(n,length - n))索引,直接访问序列的任何部分上的单精度前缀和。

实现存在于Haskell、COQ、F**、斯卡拉、Java、C、Culjule、C.*等语言中。

您可以使用它们来实现优先级搜索队列、间隔映射、具有快速头部访问的绳索、映射、集合、可分类序列或几乎任何结构,在这些结构中,您可以将其表述为收集快速可分类/可索引序列上的单精度结果。

我还有一些幻灯片描述了它们的派生和使用。


一个鲜为人知,但相当漂亮的数据结构是芬威克树(有时也称为二进制索引树或位)。它存储累积和并支持O(log(n))操作。虽然累积和听起来不太令人兴奋,但它可以用来解决许多需要排序/日志(n)数据结构的问题。

IMO的主要卖点是易于实施。在解决算法问题时非常有用,否则需要对红黑/AVL树进行编码。


xor链表使用两个xor'd指针来减少双链表的存储需求。有点晦涩但整洁!


我真的很喜欢间期树。它们允许您获取一系列间隔(即开始/结束时间或其他时间间隔),并查询哪些间隔包含给定时间,或者哪些间隔在给定时间段内处于"活动"状态。查询可以在O(log n)中完成,预处理是O(log n)。


配对堆是一种堆数据结构,其实现相对简单,具有良好的实际分摊性能。


喷溅台很棒。它们就像一个普通的哈希表,只是它们保证了持续的时间查找,并且可以处理90%的利用率而不会损失性能。它们是布谷鸟散列(也是一个伟大的数据结构)的泛化。它们看起来的确是专利,但和大多数纯粹的软件专利一样,我不会担心太多。


增强的哈希算法非常有趣。线性散列是整洁的,因为它允许一次拆分散列表中的一个"桶",而不是重新刷新整个表。这对于分布式缓存特别有用。但是,使用最简单的拆分策略,最终会快速连续地拆分所有存储桶,并且表的负载系数波动非常大。

我认为螺旋散列法也非常简单。像线性散列一样,一次分割一个存储桶,并且将存储桶中不到一半的记录放入同一个新存储桶中。它非常干净和快速。但是,如果每个"bucket"都由具有类似规格的机器承载,则效率可能很低。为了充分利用硬件,您需要混合使用功能较弱和更强大的机器。


二元决策图是我最喜欢的数据结构之一,实际上是降序二元决策图(robdd)。

例如,此类结构可用于:

  • 表示一组项并对这些项执行非常快速的逻辑操作。
  • 任何布尔表达式,目的是找到表达式的所有解

注意,许多问题可以用布尔表达式表示。例如,suduku的解可以表示为布尔表达式。为布尔表达式构建一个BDD将立即生成解决方案。


区域四叉树

(引自维基百科)

The region quadtree represents a partition of space in two dimensions by decomposing the region into four equal quadrants, subquadrants, and so on with each leaf node containing data corresponding to a specific subregion. Each node in the tree either has exactly four children, or has no children (a leaf node).

这样的四叉树很好地存储空间数据,例如纬度和经度或其他类型的坐标。

这是到目前为止我在大学里最喜欢的数据结构。给这个家伙编码,然后看着它工作是相当酷的。如果你正在寻找一个能让你深思熟虑的项目,并且有点偏离常规路线的话,我强烈推荐它。无论如何,它比通常在数据结构类中分配的标准BST派生更有趣!

事实上,作为奖励,我在这里找到了课堂项目(来自弗吉尼亚理工学院)前的讲稿(pdf警告)。


我喜欢简单的for the Treaps进行有效的思想,还要superimposing堆在结构与随机的二进制搜索树的优先级在过以平衡它。P></


快速紧凑型尝试:

  • 朱迪数组:非常快速和内存高效的有序稀疏动态数组位,整数和字符串。Judy数组比任何二进制搜索树都更快、内存效率更高。

  • hat trie:一种基于高速缓存的字符串数据结构

  • 基于磁盘的字符串管理的B尝试


已计数的未排序平衡Btrees。

非常适合文本编辑器缓冲区。

网址:http://www.chiark.greennd.org.uk/~sgtataham/algorithms/cbtree.html


我有时使用反转列表来存储范围,它们通常用于在正则表达式中存储字符类。例如,请参阅http://www.ibm.com/developerworks/linux/library/l-cpinv.html

另一个好的用例是加权随机决策。假设你有一个符号和相关概率的列表,你想根据这些概率随机选取它们。

1
2
3
   a => 0.1
   b => 0.5
   c => 0.4

然后你对所有的概率做一个连续的总和:

1
  (0.1, 0.6, 1.0)

这是你的反演表。您可以生成一个介于0和1之间的随机数,并在列表中找到下一个较高条目的索引。你可以用二进制搜索来实现,因为它是经过排序的。一旦获得了索引,就可以在原始列表中查找符号。

如果你有n符号,你有O(n)准备时间,然后O(log(n))为每一个随机选择的符号提供时间,与重量分布无关。

反转列表的变化使用负数来表示范围的终点,这使得计算在某个点上重叠的范围非常容易。请参阅http://www.perlmunks.org/index.pl?例如,node_id=841368。


阿恩安德森树是红黑树的一个简单的替代品,红黑树只有正确的链接才能是红色的。这大大简化了维护,同时保持了与红黑树相同的性能。原始文件给出了一个插入和删除的漂亮和简短的实现。


DAWG是一种特殊的树,类似的子树被压缩成单亲。我扩展了修改过的DAWG,并提出了一个漂亮的数据结构,称为assdawg(anagram search sorted dawg)。其工作方式是每当一个字符串插入到DAWG中时,首先对其进行桶排序,然后插入,并且叶节点持有一个额外的数字,指示如果我们从根到达叶节点,哪些排列是有效的。这有两个极好的优点:

  • 由于我在插入前对字符串进行排序,并且由于DAWG自然地折叠了类似的子树,所以我得到了很高的压缩级别(例如,"e a t"、"a t e"、"t e a"都变为1路径a-e-t,在叶节点处有一个数字列表,表明a-e-t的排列是有效的)。
  • 现在搜索给定字符串的变位是非常快速和简单的,因为从根到叶的路径使用排列数在叶节点保存该路径的所有有效变位。

  • 看看唐纳德·克努斯(DonaldKnuth)提出的侧堆。

    http://stanford-online.stanford.edu/seminals/knuth/071203-knuth-300.asx


    zobrist散列是一个散列函数,通常用于表示棋盘位置(如在国际象棋中),但肯定还有其他用途。它的一个优点是可以随着主板的更新而递增更新。


    芬威克树(或二元索引树)是一个值得添加到一个工具包。如果您有一个计数器数组,并且在查询累积计数(如PPM压缩)时需要不断更新它们,那么Fenwick树将在O(log n)时间内执行所有操作,并且不需要额外的空间。另请参阅本Topcoder教程以获得良好的介绍。


    我喜欢字符串处理的后缀树和数组,平衡列表的跳过列表,自动平衡树的展开树


    bk trees或burkhard-keller trees是一种基于树的数据结构,可用于快速查找字符串的近匹配项。


    splay树是很酷。他们reorder themselves出招的方式,最接近queried often to the根元素。P></


    远离所有这些图形结构,我只喜欢简单的环缓冲区。

    当正确实现时,您可以在保持性能的同时,甚至改善性能的同时,严重地减少内存占用。


    可以使用最小堆在恒定时间内查找最小元素,也可以使用最大堆查找最大元素。但如果你想同时做这两个手术呢?可以使用最小-最大值在恒定时间内执行这两个操作。它通过使用最小-最大排序来工作:交替使用连续树级别之间的最小和最大堆比较。


    持久数据结构


    B*-树

    它是各种各样的B-树,以更昂贵的插入成本高效地进行搜索。


    根据所提到的Bloom过滤器,可删除Bloom过滤器(DLBF)在某些方面优于基本计数变量。见http://arxiv.org/abs/1005.0352


    使用两个堆栈实现的队列具有相当大的空间效率(而不是使用一个链接列表,该列表至少有1个额外的指针/引用开销)。

    如何使用两个堆栈实现队列?

    当排队的人很多的时候,这对我很有效。如果我在一个指针上保存8个字节,这意味着具有一百万个条目的队列将保存大约8MB的RAM。


    跳过列表实际上非常棒:http://en.wikipedia.org/wiki/skip_列表


    三叉树

    • 快速前缀搜索(用于增量自动完成等)
    • 部分匹配(当你想在一个字符串的X汉明距离内找到所有单词时)
    • 通配符搜索

    很容易实现。


    优先级deque比维护两个具有不同订单的单独优先级队列要便宜。http://www.alexandria.ucsb.edu/middleware/javadoc/edu/ucsb/adl/middleware/prioritydeque.htmlhttp://cphstl.dk/report/priority-deque/cphstl-report-2001-14.pdf


    我认为保罗·费拉吉纳和乔瓦尼·曼奇尼的FM指数真的很酷。尤其是在生物信息学领域。它本质上是一个压缩的全文索引,利用后缀数组和引用文本的Burrows-Wheeler转换的组合。可以在不解压缩整个索引的情况下搜索索引。


    我个人认为稀疏矩阵数据结构非常有趣。http://www.netlib.org/linalg/html_模板/node90.html

    著名的布拉斯图书馆使用这些。当你处理含有100000行和列的线性系统时,使用它们变得非常重要。其中一些还类似于计算机图形中常见的紧凑网格(基本上类似于桶排序网格)。http://www.cs.kuleuven.be/~ares/publications/ld08cfrgrt/ld08cfrgrt.pdf

    另外,就计算机图形而言,Mac网格有点有趣,但仅仅是因为它们很聪明。http://www.seas.upenn.edu/~cis665/projects/liquition_665_report.pdf


    PQ树


    角缝数据结构。总结如下:

    Corner stitching is a technique for
    representing rectangular
    two-dimensional objects. It appears to
    be especially well-suited for
    interactive editing systems for VLSI
    layouts. The data structure has two
    important features: first, empty space
    is represented explicitly; and second,
    rectangular areas are stitched
    together at their corners like a
    patchwork quilt. This organization
    results in fast algorithms (linear
    time or better) for searching,
    creation, deletion, stretching, and
    compaction. The algorithms are
    presented under a simplified model of
    VLSI circuits, and the storage
    requirements of the structure are
    discussed. Measurements indicate that
    corner stitching requires
    approximately three times as much
    memory space as the simplest possible
    representation.


    正确的字符串数据结构。几乎每一个程序员都会满足于某种语言对结构的任何本地支持,而这种支持通常是无效的(特别是对于构建字符串,您需要一个单独的类或其他的类)。

    最糟糕的情况是在C中将字符串视为字符数组,并且为了安全起见依赖于空字节。


    Patricia——检索字母数字编码信息的实用算法,D.R.Morrison(1968年)。

    帕特里夏树与特里亚树有关。尝试的问题是,当密钥集是稀疏的,即当实际密钥构成潜在密钥集的一小部分时,就像通常情况一样,trie中的许多(大多数)内部节点只有一个后代。这使得trie具有很高的空间复杂性。

    http://www.csse.monash.edu.au/~劳埃德/tildalegds/tree/patricia/


    斗旅

    它们在Apache中广泛使用。基本上,它们是一个链表,在一个环中循环。我不确定它们是否在Apache和Apache模块之外使用,但它们适合作为一个很酷但鲜为人知的数据结构。桶是一些任意数据的容器,桶旅是桶的集合。其思想是您希望能够在结构中的任何点修改和插入数据。

    假设您有一个bucket旅,其中包含一个HTML文档,每个bucket有一个字符。要将所有<>符号转换为<>实体。当遇到<>符号时,bucket旅允许您在旅中插入一些额外的bucket,以适应实体所需的额外字符。因为斗旅在一个环,你可以向后或向前插入。这比使用简单的缓冲区要容易得多(在C语言中)。

    关于斗旅的一些参考资料如下:

    阿帕奇水桶旅参考

    水桶旅导论


    不相交集林允许快速的成员查询和联合操作,并且在Kruskal的最小生成树算法中最著名。

    真正酷的是,两个操作的运行时间都与Ackermann函数的倒数成正比,这使得它成为"最快"的非恒定时间数据结构。


    我不确定此数据结构是否有名称,但用于包含在Boost中的拟议tokenmap数据结构有点有趣。它是一个动态可调整大小的映射,其中查找不仅是O(1),而且是简单的数组访问。我写了关于这个数据结构的大部分背景资料,描述了它如何工作的基本原理。

    操作系统使用标记映射将文件或资源句柄映射到表示文件或资源的数据结构。


    delta-list/delta-queue在cron或事件模拟器等程序中用于计算下一个事件何时触发。http://everything2.com/title/delta+列表http://www.cs.iastate.edu/~cs554/lec_notes/delta_clock.pdf


    Burrows–Wheeler变换(块排序压缩)

    它的压缩基本算法。假设您想要压缩文本文件上的行。你会说,如果你对行进行排序,就会丢失信息。但是bwt的工作原理是这样的——它通过对输入进行排序,保留整数索引来恢复原始顺序,从而大大降低了熵。


    我认为循环排序是一种非常整洁的排序算法。

    这是一种排序算法,用于最小化总写入次数。这在处理闪存时特别有用,因为闪存的寿命与写入量成正比。这是维基百科的文章,但我建议你去第一个链接。(漂亮的视觉效果!)


    多边形网格的半边缘数据结构和带翼边缘。

    对计算几何算法有用。


    我以前很喜欢WPL树。使树枝的加权路径长度最小化的树变种。权重由节点访问决定,因此频繁访问的节点迁移到更靠近根的位置。不知道它们和八字树相比如何,因为我从未用过它们。


    其他人已经提出了Burkhard-Keller树,但我想我可能会再次提到它们,以便插入我自己的实现。:)

    http://well-adjusted.de/mspace.py/index.html调整良好

    有更快的实现(请参阅ActiveState的Python配方或其他语言的实现),但我认为/希望我的代码有助于理解这些数据结构。

    顺便说一下,BK树和VP树都可以用于搜索相似的字符串。只要距离函数满足几个条件(正性、对称性、三角形不等式),就可以对任意对象进行相似性搜索。


    外面有一个聪明的数据结构,它使用数组保存元素的数据,但是数组在一个链接列表/数组中链接在一起。

    这确实有一个优势,那就是相对于元素的迭代非常快(比纯链表方法快),并且在内存中移动带有元素的数组和/或(取消)分配的成本最低。(正因为如此,这种数据结构对于模拟材料很有用)。

    我从这里知道的:

    http://software.intel.com/en-us/blogs/2010/03/26/linked-list-verses-array/

    "…另外一个数组被分配并链接到粒子数组的单元列表中。这在某些方面类似于tbb如何实现其并发容器。"(这是关于链表与数组的其他性能)


    环境跟踪递归结构。

    编译器使用递归结构,但与树不同。内部范围具有指向封闭范围的指针,因此嵌套是由内向外的。验证变量是否在作用域中是从内部作用域到封闭作用域的递归调用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    public class Env
    {    
        HashMap<String, Object> map;
        Env                     outer;

        Env()
        {
            outer = null;
            map = new HashMap();
        }

        Env(Env o)
        {
            outer = o;
            map = new HashMap();
        }

        void put(String key, Object value)
        {
            map.put(key, value);
        }

        Object get(String key)
        {
            if (map.containsKey(key))
            {
                return map.get(key);
            }
            if (outer != null)
            {
                return outer.get(key);
            }
            return null;
        }

        Env push()
        {
            return new Env(this);
        }

        Env pop()
        {
            return outer;
        }
    }

    我不确定这个结构是否有名称。我称之为一份由内而外的清单。


    二项式堆有许多有趣的属性,其中最有用的是合并。


    • 二进制决策图(我很喜欢很好的数据结构的布尔方程,representing a,和解决他们。在大多情of things for effective)
    • 堆(where the parent of a树节点的关系总是维护some of the children to the for instance,节点,节点是the parent of a总是比它大的孩子(each of Max堆))
    • queues priority(真的只是堆堆和最小-最大-维持秩序很好,有很多of the of the item元素例如with the highest value is to be removed做第一)
    • 哈希表(与奇特的学院,在查找和处理策略,缓冲区溢出桶)
    • 平衡二叉搜索树(each of these have their自己的优势)
      • Rb(整体良好的树,当inserting除尘和迭代,查找,在安序时尚)
      • (AVL树的查找快比Rb和Rb的非常相似,但其他)
      • (splay树的查找快recently used for when are to be reused likely nodes)
      • 融合-树(甚至更好,让exploiting倍频为快速查找时报)
      • B +树(used for密封在数据库和文件系统,采用高效latency读/写from when to is to the index(重要)。
    • 空间指数(Whether for for querying优秀点/线/ / /圈矩形域上的立方体是在邻近或包含在Close to each other)
      • BSP树
      • 四叉树
      • 八叉树
      • 范围树
      • 许多不同的树相似,但slightly of different dimensions,and
    • 区间树(测距intervals重叠良好,线性)
    • 图提出
      • 列表(list of a基本adjacency边)
      • adjacency导向矩阵(representing a table of a图的边与边的单位。很快换图的遍历)

    这些化合物可以是如何想的。there are more about维基百科甚至在线数据结构P></


    直角三角形网络

    漂亮简单的方法来适应细分网格。拆分和合并操作每个都只是几行代码。


    当我读到一些与RMQ和LCA相关的算法时,我偶然发现了另一个数据结构笛卡尔树。在笛卡尔树中,两个节点之间的最小公共祖先是它们之间的最小节点。将RMQ问题转换为LCA是很有用的。