c++ - 没有 O(1) 操作来连接来自两个 forward_lists 的元素?

标签 c++ complexity-theory c++11

在阅读 C++11 和 N2543 的 FCD 中的 forward_list 时我偶然发现了一个特定的 splice_after 重载(稍微简化,让 citconst_iterator):

void splice_after(cit pos, forward_list<T>& x, cit first, cit last);

行为是在 pos 之后 (first,last) 之间的所有内容都移动到 this。因此:

  this: 1 2 3 4 5 6           x: 11 12 13 14 15 16
          ^pos                      ^first   ^last
will become:
  this: 1 2 13 14 3 4 5 6     x: 11 12       15 16
          ^pos                      ^first   ^last

描述包括复杂性:

Complexity: O(distance(first, last))

我可以看到这是因为需要调整 PREDECESSOR(last).next = pos.next,而 forward_list 不允许这种情况发生在 O (1).

好的,但是在 O(1) 中加入两个 单链表 不是这种简单数据结构的优势之一吗?因此我想知道 -- forward_list 上是否没有任何操作可以拼接/合并/加入 O(1) 中的任意数量的元素?

当然,算法非常简单。只需要一个操作名称(伪代码):(更新通过集成 Kerreks 答案)

temp_this  =   pos.next;
temp_that  =  last.next;
  pos.next = first.next;
 last.next =  temp_this;
first.next =  temp_that;

结果有点不同,因为移动的不是(first,last),而是(first,last]

  this: 1 2 3 4 5 6 7               x: 11 12 13 14 15 16 17
          ^pos                            ^first      ^last
will become:
  this: 1 2 13 14 15 16 3 4 5 6 7   x: 11 12             17
          ^pos       ^last                ^first   

我认为这是一种与前一种一样合理的操作,人们可能愿意这样做——特别是如果它具有 O(1) 的好处。

  • 我是否忽略了对许多元素的 O(1) 运算?
  • 或者我的假设是错误的,即 (first,last] 可能对移动范围有用?
  • 还是O(1)算法有错误?

最佳答案

让我先给出一个你的 O(1) 拼接算法的修正版本,并举个例子:

temp_this  =   pos.next;
temp_that  =  last.next;

  pos.next = first.next;
 last.next =  temp_this;
first.next =  temp_that;

(健全性检查是观察每个变量精确出现两次,一次设置一次,一次获取。)

例子:

    pos.next                           last.next
    v                                  v
1 2 3 4 5 6 7        11 12 13 14 15 16 17 #    
  ^                     ^           ^     ^
  pos                   first       last  end             


becomes:

This:     1 2 13 14 15 16 3 4 5 6 7

That:   11 12             17

现在我们看到,为了拼接到 that 列表的末尾,我们需要在 end()。但是,在恒定时间内不存在这样的迭代器。所以基本上线性成本来自于以一种或另一种方式发现最终的迭代器:要么在 O(n) 时间内预先计算它并使用你的算法,要么你只是在线性时间内一个接一个地拼接。

(假设您可以实现自己的单链表,该列表将为 before_end 存储一个额外的迭代器,您必须在相关操作期间保持更新。)

关于c++ - 没有 O(1) 操作来连接来自两个 forward_lists 的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7714561/

相关文章:

c++ - CMake 和不同版本的 Visual Studio

c++ - 如何让我的模板只需要绝对必要的功能

algorithm - 寻找这段代码的 Big-O

c++ - OpenCV 关键点响应是大还是小?

c++ - 如何在后台启动 GUI 应用程序?

computer-science - 不是NP完全的NP难问题难吗?

javascript - 是否有用于 Javascript 的内存限制工作量证明概念?

php - Swig 将 vector<std::string> 转换为原生 PHP 数组

c++ - 你应该为 std::unordered_map 迭代器使用引用吗?

c++11 - 在C++中,如何使用for_each反向迭代数组?