在恒定时间内拼接完整列表

时间:2015-10-14 12:46:31

标签: c++ list stdlist

我试图在恒定时间内拼接(连接)两个完整的std :: list。从阅读文档和其他问题 (How to do range splice in constant time with std::forward_list?),我有两个澄清问题:

  1. 是否可以在固定时间内拼接两个std :: list并保留每个列表的完整列表?
  2. 我的理解是,这个功能可以通过创建我自己的列表数据结构来实现 - 并使用类似于以下的函数(伪代码):

    List joinLists(List list1, List list2) {
    
      list1->tail = list2->head;
    
      list1->tail = list2->tail;
    
      return list1;
    
    }
    
  3. 这是真的吗?如果没有,如果有人能帮我理解这里发生的事情,我将不胜感激。我觉得我错过了什么......

    我正在使用的代码在这里:

     auto simple_sorter = [this, numCores](std::vector<std::vector<std::list<unsigned int>>>& buckets_small_, std::vector<std::list<unsigned int>>& buckets_large_, std::vector<bool>& finished_, unsigned int range_low, unsigned int range_high, int thread_number)
    {
        //.. irrelevant
    
        //Combine small buckets into single large bucket per thread
        for(unsigned int i = 0; i < numCores; ++i) {
            std::list<unsigned int> list1 = buckets_large_[thread_number];
            list1.splice(list1.end(), buckets_small_[i][thread_number]);
    
        //...
    };
    

    (注意:Boost /其他库不是一个选项)

2 个答案:

答案 0 :(得分:2)

  1. 是的,std::list::splice以这种方式工作(有O(1)复杂度)(1)
  2.   

    不复制或移动任何元素,只重新指向列表节点的内部指针。

    1. 假设有一个抽象的单链表,你可以

      list1->back->next = list2->front;
      list1->size += list2->size;
      

      对于双链表,您也可以

      list2->front->prev = list1->back;
      

      如果要在list2的{​​{1}}元素之后插入n的元素,则需要找到该元素并执行相同的操作

      list1

      在任何一种情况下,都不会复制数据,只需在此处交换指针即可。

答案 1 :(得分:-1)

(下面是伪代码)

拼接是交织在一起的:

new_list = list1[0], list2[0], list1[1], list2[1], ...

连接将两个列表连接在一起:

new_list = list1, list2

(下面是(稍微不那么伪)未经测试的代码)

拼接:

List splice(List list1, List list2){
  List<stuff> things ;
  List<stuff> * small_list = list1.size() > list2.size() ? &list2 : &list1 ;
  List<stuff> * big_list = list1.size() > list2.size() ? &list1 : &list2 ;
  for(int i = 0 ; i < small_list->size() ; i++ ){
    things << list1[i] << list2[i] ;
  }
  for(int i = small_list->size() ; i < big_list->size()){
    things << (*big_list)[i] ;
  }
  return things ;
}

非常确定你必须在返回值和参数中定义你的列表包含的内容(或者使用多态的模板,这些都超出了我的目的)

免责声明:如果这是有效的c ++,我会被红宝石宠坏并被遗忘......