Questions tagged «search-trees»

有关搜索树的问题,搜索树是用于存储排序数据以进行有效访问的一类数据结构。

4
为什么红黑树如此受欢迎?
在我看来,似乎到处都在使用红黑树(std::set在C ++,SortedDictionaryC#等中)实现数据结构。 在我的算法课程中刚刚覆盖了(a,b),红黑和AVL树之后,这就是我的收获(也是从问问教授,翻阅几本书并仔细研究一下)得出的: AVL树的平均深度小于红黑树,因此在AVL树中搜索值的速度始终更快。 与AVL树相比,红黑树进行结构调整以平衡自身的可能性要小一些,这可能会使它们的插入/删除速度更快。我可能会说,因为这将取决于对树的结构更改的成本,因为这将在很大程度上取决于运行时和隐含(当树是不可变的时,功能语言是否也可能完全不同?) 网上有很多基准可以比较AVL和红黑树,但令我惊讶的是,我的教授基本上说过,通常您会做以下两件事之一: 要么您根本就不在乎性能,在这种情况下,大多数情况下AVL与Red-black的10-20%的差异根本不重要。 或者,您真的很在乎性能,在这种情况下,您会抛弃AVL树和红黑树,并选择B树,可以对B树进行调整以使其工作得更好(或(a,b)树),我将所有这些都放在一个篮子里。) 这样做的原因是因为B树将数据更紧凑地存储在内存中(一个节点包含许多值),因此缓存未命中的情况将大大减少。您还可以根据用例来调整实现,并使B树的顺序取决于CPU缓存大小等。 问题在于,我几乎找不到任何可以分析现实硬件上不同实现的搜索树实际使用情况的资源。我浏览过许多有关算法的书,但没有发现可以将不同的树变体进行比较的任何东西,除了表明一棵树的平均深度比另一棵树小(这并没有真正说明树的行为方式)在实际程序中。) 话虽这么说,是否有一个特定的原因为什么到处都使用红黑树,而根据上述内容,B树应该胜过它们?(作为唯一的基准测试,我还可以看到http://lh3lh3.users.sourceforge.net/udb.shtml,但这可能只是具体实现的问题)。还是为什么每个人都使用Red-black树是因为它们很容易实现,或者换句话说,很难实现不好呢? 另外,当人们进入功能语言领域时,这将如何改变?似乎Clojure和Scala都使用Hash数组映射的trys,其中Clojure使用32的分支因子。

1
想象一棵红黑的树。是否总会有一系列插入和删除操作来创建它?
让我们假设以下是红黑树的定义: 它是二叉搜索树。 每个节点都被涂成红色或黑色。根是黑色的。 通过边连接的两个节点不能同时为红色。 像Wiki一样,这应该是NIL叶的良好定义。NIL叶为黑色。 从根到任何NIL叶的路径都包含相同数量的黑色节点。 题 假设您已经为红黑树实现了insert和delete操作。现在,如果为您提供了有效的红黑树,是否总有一个构造它的insert和序列delete? 动机 这个问题是由这个问题和这个问题的讨论引起的。 就个人而言,我确实相信,如果您想象一个仅由黑色节点组成的有效红黑树(这意味着您正在想象一个完美平衡的树),那么将有一个由insert和delete构成的序列。然而, 我不知道如何准确证明 我也对更一般的情况感兴趣

2
并非所有的红黑树都是平衡的?
直观地,“平衡树”应该是每个节点的左右子树必须具有“大约相同”数目的节点的树。 当然,当我们谈论红黑树*(请参阅最后的定义)时,实际上是指它们在高度上是平衡的,从某种意义上说,它们是平衡的。 假设我们尝试将上述直觉形式化如下: 定义:二叉树被称为μμ\mu -balanced,具有0≤μ≤120≤μ≤120 \le \mu \leq \frac{1}{2},如果对于每个节点,不等式NNN μ≤|NL|+1|N|+1≤1−μμ≤|NL|+1|N|+1≤1−μ \mu \le \frac{|N_L| + 1}{|N| + 1} \le 1 - \mu 对于每个,都有一个节点,上面的语句失败。是和的左子树中的节点数。是树下以为根(包括根)的节点数。μ′>μμ′>μ\mu' \gt \mu|NL||NL||N_L|NNN|N||N||N|NNN 我相信,在有关此主题的一些文献中,这些树被称为重量平衡树。 可以证明,如果具有节点的二叉树是平衡的(对于常数),那么树的高度是,因此保持了很好的搜索属性。nnnμμ\muμ>0μ>0\mu \gt 0O(logn)O(log⁡n)\mathcal{O}(\log n) 所以问题是: 是否有一些使每个足够大的红黑树达到平衡?μ>0μ>0\mu \gt 0μμ\mu 我们使用的Red-Black树的定义(来自Cormen等人的Introduction to Algorithms): 二进制搜索树,其中每个节点的颜色为红色或黑色, 根是黑色的 所有NULL节点均为黑色 如果节点为红色,则其两个子节点均为黑色。 对于每个节点,从该节点到后代NULL节点的所有路径都具有相同数量的黑色节点。 注意:在上面的 balanced 的定义中,我们不计算NULL节点。(尽管我相信这是否重要)。μμ\mu

2
为什么C的void类型不同于Empty / Bottom类型?
维基百科以及我发现的其他来源都将C的void类型列为单位类型,而不是空类型。我觉得这很混乱,因为在我看来,它void更适合于空/底类型的定义。 void据我所知,没有价值观存在。 返回类型为void的函数指定该函数不返回任何内容,因此只能执行某些副作用。 类型的指针void*是所有其他指针类型的子类型。同样,void*在C中进行来回转换是隐式的。 我不确定最后一点是否可以作为void空类型的参数,void*或多或少是与无关的特例void。 另一方面,void它本身不是所有其他类型的子类型,据我所知,这是将类型作为底部类型的要求。
28 type-theory  c  logic  modal-logic  coq  equality  coinduction  artificial-intelligence  computer-architecture  compilers  asymptotics  formal-languages  asymptotics  landau-notation  asymptotics  turing-machines  optimization  decision-problem  rice-theorem  algorithms  arithmetic  floating-point  automata  finite-automata  data-structures  search-trees  balanced-search-trees  complexity-theory  asymptotics  amortized-analysis  complexity-theory  graphs  np-complete  reductions  np-hard  algorithms  string-metrics  computability  artificial-intelligence  halting-problem  turing-machines  computation-models  graph-theory  terminology  complexity-theory  decision-problem  polynomial-time  algorithms  algorithm-analysis  optimization  runtime-analysis  loops  turing-machines  computation-models  recurrence-relation  master-theorem  complexity-theory  asymptotics  parallel-computing  landau-notation  terminology  optimization  decision-problem  complexity-theory  polynomial-time  counting  coding-theory  permutations  encoding-scheme  error-correcting-codes  machine-learning  natural-language-processing  algorithms  graphs  social-networks  network-analysis  relational-algebra  constraint-satisfaction  polymorphisms  algorithms  graphs  trees 

1
为什么展开树旋转算法会同时考虑父节点和祖父母节点?
我不太了解为什么splay树数据结构中的轮换不仅要考虑评级节点的父级,还要考虑祖父母(zig-zag和zig-zig操作)。为什么以下方法不起作用: 例如,当我们插入树的新节点时,我们检查是否插入到左或右子树中。如果插入到左侧,则将结果向右旋转,反之亦然,将右子树旋转。递归就是这样 Tree insert(Tree root, Key k){ if(k < root.key){ root.setLeft(insert(root.getLeft(), key); return rotateRight(root); } //vice versa for right subtree } 那应该避免整个“花花公子”程序,你不觉得吗?

1
AVL树不平衡吗?
在上一个问题中,有一个平衡树的定义和一个关于红黑树的问题。 这个问题是要问同样的问题,但对于AVL树。 问题是,鉴于平衡树的定义与其他问题相同,μμ\mu 是否有一些使所有足够大的AVL树达到平衡?μμ > 0μ>0\mu \gt 0μμ\mu 我认为AVL树只有一种定义,没有歧义。

1
无锁,恒定的更新时间并发树数据结构?
我最近阅读了一些文献,并且发现了一些相当有趣的数据结构。 我研究了各种不同的方法来将更新时间降低到最坏情况下的更新时间[1-7]。O(1)O(1)\mathcal{O}(1) 最近,我开始研究无锁数据结构,以支持有效的并发访问。 在无锁数据结构的实现中是否使用了这些最坏情况下的更新时间技术?O(1)O(1)\mathcal{O}(1) 我问是因为 在我看来,它们似乎是这种“理论上的增强”的明显实践扩展。 Tarjan,Robert Endre。“以O(1)循环更新平衡的搜索树。”《信息处理快报》,第16号,否。5(1983):253 – 257。 Driscoll,JR,N Sarnak,DD Sleator和RE Tarjan。“使数据结构持久化”。在第18届ACM计算理论年度学术会议论文集中,109-121。STOC '86。美国纽约州:ACM,1986年。 Levcopoulos,C。和Mark H. Overmars。“具有O(1)最坏情况更新时间的平衡搜索树。” Acta Inf。26号 3(1988年11月):269-277。 鲁道夫·弗莱舍。具有O(1)最坏情况更新时间的简单平衡搜索树 Dietz,Paul F和Rajeev Raman。“一个恒定的更新时间手指搜索树。”信息处理,第52号信。3(1994):147 – 154。 Lagogiannis,George,Christos Makris,Yannis Panagis,Spyros Sioutas和Kostas Tsichlas。“具有最坏情况下恒定更新时间的新动态平衡搜索树。” J. Autom。郎 梳子。8号 4(2003年7月):607-632。 Brodal,GerthStølting,George Lagogiannis,Christos Makris,Athanasios Tsakalidis和Kostas Tsichlas。“指针机器中的最佳手指搜索树。” J. Comput。Syst。科学 67号 2(2003年9月):381-418。

2
创建自排序二叉树
我有一个作业,需要使用二叉搜索树并将其更改为自身自定序,以使访问最多(优先级更高)的项目位于树的顶部,根是访问最多的节点。 教授给了我可以使用的BST和节点结构,但是在插入事物时试图让我的脑袋绕开更新树的算法,这使我感到困惑。 我知道随着插入的进行,它会检查当前节点的数据是否小于或大于当前节点,然后递归地以正确的方向运行,直到找到空指针并将其自身插入那里。并将其插入后将优先级增加1。 template <class Type> void BinarySearchTree<Type> :: insert( const Type & x, BinaryNode<Type> * & t ) { if( t == NULL ) t = new BinaryNode<Type>( x, NULL, NULL ); else if( x < t->element ) insert( x, t->left ); else if( t->element < x ) insert( …

2
将二叉树上色为红黑树
常见的采访问题是给出一种算法,以确定给定的二叉树是否高度平衡(AVL树定义)。 我想知道我们是否可以对红黑树做类似的事情。 给定一个任意的未着色的二叉树(具有NULL节点),是否存在一种“快速”算法,该算法可以确定我们是否可以对节点Red / Black进行着色(并查找着色),以便它们满足Red-Black树的所有属性(这个问题的定义)? 最初的想法是,我们可以删除NULL节点,然后尝试递归地验证生成的树是否可以是一棵红黑树,但这似乎没有任何用处。 我在网上做了简短的搜索,但是似乎找不到任何可以解决这个问题的文件。 我可能错过了一些简单的东西。

3
没有数组的记忆
在Cormen等人的“算法简介”中,第15.3节动态编程的元素对记忆的解释如下: 记忆的递归算法为每个子问题的解决方案在表中维护一个条目。每个表条目最初都包含一个特殊值,以指示该条目尚未填写。当递归算法展开时,第一次遇到子问题时,将计算其解决方案,然后将其存储在表中。以后每次遇到此子问题时,我们只需查找表中存储的值并返回它。 并且添加了一个脚注: 这种方法的前提是我们知道所有可能的子问题参数的集合,并且已经建立了表位置和子问题之间的关系。另一种更通用的方法是通过使用以子问题参数作为键的哈希来记忆。 是否有任何众所周知的DP问题需要(或使其更容易)将已存储的值存储在字典中,而不是在(多维)数组中? 背景:如果有什么用,这个问题的原因是我正试图将(自平衡)二进制搜索树的概念激发给刚刚看过动态编程的人们。

2
在BST中搜索时可能的搜索路径数
我有以下问题,但没有答案。如果我的方法正确,我将不胜感激: 问:在二叉搜索树中搜索键值60时,遍历包含键值10、20、40、50、70、80、90的节点,而不必按给定的顺序进行。从包含值60的根节点开始的搜索路径中,这些键值可以出现多少种不同的顺序? (A)35(B)64(C)128(D)5040 从这个问题中,我了解到遍历必须包括所有给定的节点,最终我们必须达到键60。例如,这样的组合之一是: 10、20、40、50、90、80、70、60。 由于我们必须遍历上面给出的所有节点,因此我们必须从10或90开始。如果我们从20开始,我们将不会达到10(因为60> 20并且将遍历20的右子树) 同样,我们不能从80开始,因为我们将无法达到90,因为80> 60,我们将在80的左子树中遍历,因此无法达到90。 取10。剩余的节点为20、40、50、70、80、90。下一个节点可以为20或90。出于前面提到的相同原因,我们不能取其他节点。 如果我们以相似的方式考虑,则在每个级别我们都有两个选择。由于有7个节点,因此前6个有2个选择,最后1个没有选择。所以完全有 2 * 2 * 2 * 2 * 2 * 2 * 12∗2∗2∗2∗2∗2∗12*2*2*2*2*2*1排列= = 6426262^6646464 这是正确的答案吗? 如果没有,更好的方法是什么? 我想概括一下。如果给出节点,则总共可能的搜索路径为2 n − 1ñnn2n − 12n−12^{n-1}



3
什么数据结构可以有效地存储整数范围?
我需要保留一个范围在0到65535之间的整数的集合,以便可以快速执行以下操作: 插入一个新的整数 插入一系列连续的整数 删除整数 删除整数以下的所有整数 测试是否存在整数 我的数据具有以下特性:它通常在集合中包含整数整数。例如,集合在某个时间点可能是: { 121, 122, 123, 124, 3201, 3202, 5897, 8912, 8913, 8914, 18823, 18824, 40891 } 最简单的方法就是使用像C ++ std :: set这样的平衡二叉树,但是,使用它,我没有利用我经常会有大量数字的事实。也许最好存储一系列范围?但这意味着,如果要删除范围中间的整数,则需要将其分解;如果要填充两个范围之间的空格,则必须将其合并在一起。 是否存在任何适合此问题的现有数据结构?


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.