带有一些操作的双重链表

时间:2014-10-13 19:09:29

标签: algorithm data-structures linked-list code-analysis doubly-linked-list

对于具有数字元素的双向链表Q,我们有一个指向第一个和最后一个元素的指针,我们定义了两个操作。

Delete (k): delete k first elements from Q.

Append (c), check the last element from `Q`, if this value  bigger than c, delete this elements and repeat it again until the last element is lower or equal to `c` (or empty `Q`), then insert c as last elements of Q`.` 

如果我们在空列表n上以Q次的任意顺序重复这两个操作的序列,那么这些操作的所有成本的总和接近2n。为什么我的导师到达2n?任何提示或想法都表示赞赏。

2 个答案:

答案 0 :(得分:0)

  

如果我们以任意顺序重复这些操作n次空   list这些操作的所有成本的Q总和接近2n

它实际上是O(n),因为我们知道列表Q是空的。

DoStuff(list Q, int n):
    for(int i = 0; i < n; i++)
        Q.Delete(k) //O(k)
        Q.Append(c) //O(sizeof(Q))
        //or
        //Q.Append(c) //O(sizeof(Q))
        //Q.Delete(k) //O(k)

其中n是迭代次数。

现在说列表不是空的,那么我们就会O(n*(sizeof(Q)+k))。对此的解释如下:

假设Delete (k)更糟糕的情况是从Q中删除k个第一个元素,其中k的大小为Q,那么我们将删除n个元素。但是,更准确地说O(k)因为您始终只删除第一个k元素。

假设Append (c)的情况更糟,Q内的所有元素都大于值c。这将从尾节点开始,并从Q删除所有节点。 按顺序

Delete(k) //O(k)
Append(c) //O(sizeof(Q))

或者

Append(c) //O(sizeof(Q))
Delete(k) //O(k)

更糟糕的情况是,这两个命令是O(sizeof(Q)+k)。现在我们知道我们必须进行n次迭代,所以我们最终得到O(n*(sizeof(Q)+k))

至于你的教授所说的,我能够 想象 你的教授说2n的唯一原因是因为2函数正在称为n次。因此2n

答案 1 :(得分:0)

当我们在空列表Q 上以“Delete次”的任意顺序“重复Appendn时,会调用Append {{ 1}}次;因此,执行了n列表元素插入。

由于列表最初为空,因此它永远不会包含超过n个元素;因此,最多n个列表元素删除是在nDelete的组合中执行的。

因此AppendDelete中每个Append中的循环总数不超过2 Append

总而言之,程序的任何部分执行时间超过2 n次(单独计算列表元素插入,列表元素删除和列表元素访问可能常见的代码)。

n始终为0且k非递减(包括始终为0)时,成本最低:我们有c列表元素插入,n列表元素读取(一个返回空),n空白测试,n元素比较,没有删除。因此,成本随参数变化很大。

注意:“这些操作的所有成本的总和接近2 n-1 ”是不明确的,因此甚至没有错。更糟糕的是,如果列表元素删除,由于一些运气不好(例如代码缓存未命中,调试代码......)比其余部分慢得多,则可能是代码持续时间变化很大因素(远高于2),具体取决于参数。因此,执行时间不是总是大约2 n ”,因为它的任何内容意义。

更新:在comment中,我们被告知列表元素插入和删除具有相同的成本1.有n列表元素插入,以及0到n列表元素删除。因此,如果我们忽略其他成本(合理的是内存分配成本占主导地位),总成本约为n到约2 n,具体取决于参数。此外,对于许多参数(包括大多数时间n> = 1),列表元素删除几乎k,因此如果坚持最好的话,成本约为2 n猜测,例如在多项选择问题中使用(a)n + n(b)k(c)2 n(d)3 n作为唯一的选择。