在C ++中迭代部分列表

时间:2013-08-13 21:06:58

标签: c++ iterator

我是C ++的新手,我正在进行合并排序的实现,以帮助我熟悉语言。

目前我有一个整数列表,我想创建2个子列表,并将原始列表的前半部分存储到名为“left”的列表中,将剩下的一半存储到名为“right”的列表中

例如:假设我的原始列表数据是16,24,56,12,89;我想迭代这个列表添加 16,24到新的子列表'left' 并将56,12,89添加到子列表'right' 左边会导致[16,24] 正确的是[56,12,89]

这是我现在的代码;我应该在if语句中写什么条件? ('l'是函数参数中传递的列表的名称)

    list<int> left, right;
    int midpt = l.size()/2;
    for(listIt = l.begin(); listIt!= l.end(); listIt++){
       if () left.push_back(*listIt);
       if () right.push_back(*listIt);
    }

4 个答案:

答案 0 :(得分:6)

这可能更容易:

#include <iterator>
#include <list>

auto middle = std::next(l.begin(), l.size() / 2);

std::list<int> left(l.begin(), middle), right(middle, l.end());

这会直接从相应的范围构建两个新列表leftrightstd::next算法返回一个迭代器,该迭代器是通过给定的迭代器按给定的步数推进得到的。请注意,std::list<int>::size()在C ++ 11中具有恒定的运行时复杂性,但迭代迭代器需要花费大量工作。

答案 1 :(得分:0)

这样可行。

list<int> left, right;
int midpt = l.size()/2;
int count = 0;
for(listIt = l.begin(); listIt!= l.end(); listIt++){
   if (count++ < midpt)
       left.push_back(*listIt);
   else
       right.push_back(*listIt);
}

答案 2 :(得分:0)

使用std::list::insert代替for循环。试试 -

left.insert(l.begin(), l.begin() + midpt);
right.insert(l.begin() + midpt, l.end());

答案 3 :(得分:0)

鉴于std::list定义了一个双向链表,可能值得考虑一种不同的方法。您可以考虑将第一个元素添加到left列表中,而不是找到列表的中间位置,并将其剩余部分添加到一个列表中,而将其添加到另一个列表中,这可能是您right列表的最后一个元素。 {1}}列表,推进两个迭代器,并重复(直到迭代器相遇)。

大多数其他方法需要对列表进行线性遍历才能找到中间值,然后对两边进行线性遍历以构建两个新列表。换句话说,你遍历列表1.5次。

通过同时从正面和背面遍历,您只需遍历列表一次即可完成整个作业。就big-O复杂性而言,它们是等价的(在两种情况下都是O(N)),但在更实际的术语中,我们可以期望遍历列表一次大约一半左右再次超过1.5倍(尽管取决于列表大小,缓存可能会至少在某种程度上影响它。)