如果这个问题感觉像解决方案验证一样,但是这个问题被问到我的研究生入学考试中,并有很多骑行:

如果链接列表需要维护在排序的顺序中,将 $ n $ 元素插入 $ n $ 元素是什么?

在我看来,答案应该是 $ o(n ^ 2)$ 因为在每个插入中,我们都必须在正确的位置插入元素每个元素都必须在最后一个位置插入,给我一个时间复杂度 $ 1 + 2 + ...(n-1)+ n= o(n ^ 2)$

但是,我已经说明了我们可以首先对 $ o(n \ log n)$ 然后,我们可以将其中一个分类在 $ o(n)$ 中,给我们 $ o(n \ log n)$ < / span>。

从给定的措辞的问题,哪个解决方案更容易?在我看来,由于问题提出了“需要以排序的顺序保持联系表链接列表”,我倾向于说我们无法预先对元素进行排序,然后以排序的顺序插入它们。

有帮助吗?

解决方案

问题只表示需要按排序顺序维护目标列表。它没有对您可以选择使用的任何其他数据结构的任何其他数据结构。所提出的解决方案首先对插入的参数进行一些预处理,然后插入正确。这是问题陈述允许的。

执行此操作的实际原因,而不是插入元素然后输入,如果链接列表对象与需要它始终排序的另一个线程共享。 (在这样的场景中,您需要确保插入一个元素是原子的。)因此,这个问题不仅仅是为了奇怪而制造奇怪的要求。这是经常在真实的编程世界中提出的要求。

具有相同复杂性的另一个解决方案是将元素插入目标列表,然后将并行数据结构映射元素值维护到目标列表中的节点指针。要插入每个元素,请在映射中找到前面的元素,并在此节点后插入新元素。这假设插入过程创建列表节点(而不是填充现有的空白节点)。

这个问题比读取理解更多,而不是关于算法。这是措辞的方式,它有点诀窍问题。它有些令人沮丧的措辞,因为它依赖于精确的阅读,但不能说明一些关键假设,例如获取插入成本的元素 $ o(n)$ ,比较两个元素可以在 $ o(1)$ 中完成,并且输入域有效地无限制地(练习:提出 $ O(n)$ 算法如果输入在范围 $ [1,42] $ )中。但给定的答案是正确的。

假设没有办法使用辅助数据结构。问题声明中没有任何内容使用辅助数据结构禁止。禁止辅助数据结构的简单方法是要求 $ o(1)$ 内存开销。

请注意,即使在这个假设下,您的推理也是错误的,或者至少不精确。如果您曾经知道以正确的顺序给出元素,则可以保持指向列表尾部的指针,并继续在那里插入,这将需要 $ o(n) $ 。最坏的情况不是如果必须在目标列表中的最后一个位置插入每个元素,但在某种程度上遍历列表时达到最后一个位置。最糟糕的情况是确实 $ \ theta(n ^ 2)$ ,但要证明这一点,您必须证明查找列表中的插入点taper $ \ Theta(n)$ 时间,这要求证明您在列表中的任何指针的距离是下面的 $ \ Omega(n)$ 。如果您有一个常量<跨度类=“math-container”> $ 指针的情况,这就是这样的情况(你隐式假设 $ a= 1 $ ,在列表开始时具有单个指针),以便在 $ k / a $ 节点-Container“> $ k $ 在最坏的情况下插入。

其他提示

我知道的最佳结构是Fibonacci堆,您可以在 $ o(1)$ 中插入元素,并提取 $ O(\ log(n))$ ,这意味着如果您需要所有元素的排序顺序,它需要 $ o(n \ log(n))$ 在插入新元素时,只需花费您 $ o(1)$ ,我不知道可以跟上它的其他结构。

真的是一个棘手的问题。首先,O(NLogn)的复杂性仅适用于在其元素(比较算法)之间使用比较的算法。还有算法是非比较的算法,例如基数排序,它们的复杂性取决于要存储在存储器中的数字中的大小。因此,如果我们假设我们可以用任何算法预先对数字进行排序,那么我们也可以假设数字是自然,最大元素为M <10,因此使用基数排序您将获得最坏情况O(10n)= o(n)。如果我们不能假设,那么你就是对的。如果您只允许使用链接列表,并且没有更多(无索引任何类型),那么复杂性就是O(n ^ 2)(泡沫排序)。

应该是o(n)。 遵循算法 -

1)如果链接列表为空,则使节点为 头并返回它。

2)如果要插入的节点的值较小 而不是头节点的值,然后插入节点 在开始并使其头。

3)在循环中,之后找到相应的节点 要插入输入节点。

要找到相应的节点从头开始, 继续移动,直到您到达值的节点大于 输入节点。该节点在此之前是 适当的节点

4)在相应节点后插入节点 在步骤3中找到

许可以下: CC-BY-SA归因
不隶属于 cs.stackexchange
scroll top