【问题标题】:Are these time complexities correct这些时间复杂度是否正确
【发布时间】:2014-03-15 15:54:35
【问题描述】:

我想知道我关于以下几点的时间复杂度以及推理是否正确。

  1. 在动态数组末尾的插入是 O(1) 和其他任何地方 O(n)(因为可能需要复制和移动元素)(类似于 std::vector)
  2. 搜索单个链接列表是 O(n),因为它是线性的。
  3. 在单个链接列表中的插入和删除可以是 O(1) 或 在)。如果节点的地址可用,则为 O(1) 它的 O(n),因为需要进行线性搜索。

我会很感激对此的反馈

【问题讨论】:

  • 1.如果没有足够的空间容纳新元素,则在末尾插入可能是 O(n),并且必须将部分或全部元素复制到新的更大的存储块中。
  • 您应该准确定义 n 是什么。是容器的总​​大小还是所讨论的元素之前/之后的元素?另外:对于单个链表,必须知道前导的地址才能插入/删除,因为那是指针必须更改的地方。 (你总是知道你要插入的节点的地址)

标签: c++ data-structures big-o time-complexity


【解决方案1】:

动态数组末尾的插入是 O(1) 和 O(n) 中的任何其他位置(因为元素可能 > 需要复制和移动)(类似于 std::vector)

动态数组的摊销时间复杂度为 O(1)。 https://stackoverflow.com/a/249695/1866301

搜索单个链接列表是 O(n),因为它是线性的。

是的

单个链表中的插入和删除可能是 O(1) 或 O(n)。如果是 O(1) 节点的地址是可用的,否则它的 O(n) 因为需要线性搜索。

是的,如果链表的节点由它们的地址索引,你可以得到 O(1),否则你将不得不搜索 O(n) 的链表。还有其他变体,例如搜索是对数的跳过列表,O(log n)。 http://en.wikipedia.org/wiki/Skip_list

【讨论】:

    【解决方案2】:

    1) 在动态数组末尾插入摊销 O(1)。原因是,如果插入强制重新分配,则需要将现有元素移动到 O(n) 的新内存块。如果您确保每次分配发生时数组都以常数因子增长,最终移动变得不频繁以至于变得微不足道。插入动态数组的中间需要 O(n) 来移动插入点之后的元素。

    2) 正确;通过链表搜索,无论是否排序,都是 O(n),因为在搜索过程中将访问链表的每个元素。

    3) 这也是正确的。如果您不需要排序列表,则插入单链表通常实现为添加到列表的头部,因此您只需将列表头部更新为新节点,并将新节点的下一个指针更新为成为列表的老头。这意味着插入未排序的单链表通常会被表示为 O(1) 而无需过多讨论。

    【讨论】:

      【解决方案3】:

      算法复杂度看at this cheatsheet,我拿来作为参考

      【讨论】:

        猜你喜欢
        • 2021-04-08
        • 2021-12-16
        • 1970-01-01
        • 2021-08-25
        • 1970-01-01
        • 2015-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多