【问题标题】:Is an O(log n) linked list search algorithm possible?O(log n) 链表搜索算法是否可行?
【发布时间】:2021-04-13 08:50:35
【问题描述】:

链表的搜索算法是否可能为 O(log n)?据我了解,链表可能有 O(n) 或 O(1),因为您可以选择从哪里开始,从链表的开头到结尾。知道了这一点,您能否从中间开始寻找运行时间为 O(log n) 的搜索算法?

【问题讨论】:

  • 另外,我不确定您如何想象链表中的 O(1) 搜索算法如何工作。
  • @mkrieger1 我还没有尝试过任何东西,所有这些都只是完全概念性/理论性的。如果要搜索的元素在链表的开头或结尾,那不是 O(1) 吗?
  • Big-O 表示最坏情况的摊销复杂性。元素是否位于您要查找的第一个位置无关紧要 - 这不是最坏的情况。
  • @patrickartner 说得通。
  • @PatrickArtner Big-O 也可以表示平均情况,不一定是最坏情况。

标签: python algorithm linked-list


【解决方案1】:

如果你能以某种方式跳过读取元素,那么只有可能实现比 O(n) 遍历更快的速度,除非你事先知道要跳过什么并有额外的结构来跳转到列表的某些部分,否则这是不可能的.如果您从开头或结尾开始,则必须平均搜索 n/2 个元素,然后才能找到您要查找的内容。如果您只有一个指向列表中间的指针,您仍然需要在每个方向上搜索 n/2,这无济于事。需要的是更多的结构,例如强加一个排序的标准。然后可以通过在平均情况中实现 O(log n)“跳过通道”在 O(n) 空间中实现这种“跳过”并在 O(log n) 时间内搜索。此数据结构称为skip list,它保持快速 O(log n) 插入。这些是与平衡树相同的渐近界,但在概念上更接近链表。

【讨论】:

    【解决方案2】:

    一个 O(log n) 算法需要

    • 在恒定时间内将列表分成固定数量的部分,并且
    • 确定搜索项在恒定时间内位于哪个部分。

    例如对于一个跟踪其大小的有序索引数组数据结构的二分查找算法,分割点可以直接从数组的大小中计算出来,并且可以通过以下方式判断被查找的项是在前半部分还是后半部分与分割点处的项目进行比较。

    但是对于链表,您不知道它的大小,并且必须遍历它才能找到拆分点。这是一个 O(n) 运算,所以整个算法不可能是 O(log n)。

    总的来说,第二个条件也不满足。

    【讨论】:

    • 如果你有一个排序列表,你可以动态保持一个分裂点树,创建一个跳过列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多