1

我是 C++ 新手,我正在研究合并排序的实现,以帮助自己熟悉该语言。

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

例如:假设我的原始列表数据是16、24、56、12、89;我想遍历这个列表,将 16、24 添加到新的子列表 'left' 并将 56、12、89 添加到子列表 'right' 所以 left 会导致 [16, 24] 而 right 会是 [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

4 回答 4

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());

这会直接从各自的范围构造两个新列表,left和。rightstd::next算法返回通过将给定迭代器推进给定步数而获得的迭代器。请注意,std::list<int>::size()从 C++11 开始,它具有恒定的运行时复杂性,尽管迭代迭代器需要线性量的工作。

于 2013-08-13T21:13:13.313 回答
0

鉴于它std::list定义了一个双向链表,可能值得考虑一种稍微不同的方法。left您可以考虑将第一个元素添加到列表中,将最后一个元素添加到right列表中,推进两个迭代器,而不是找到列表的中间,并将其左侧的内容添加到一个列表中,并将其右侧的内容添加到另一个列表中,并重复(直到迭代器相遇)。

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

通过同时从前面和后面遍历,您可以通过仅遍历列表一次来完成整个工作。就大 O 复杂度而言,它们是等价的(两种情况下都是 O(N)),但在更实际的情况下,我们可以期望遍历列表一次比遍历它 1.5 次快一半左右(尽管取决于列表大小,缓存可能会至少在某种程度上影响它)。

于 2013-08-13T22:32:47.997 回答
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);
}
于 2013-08-13T21:11:39.790 回答
0

使用std::list::insert而不是 for 循环。尝试 -

left.insert(l.begin(), l.begin() + midpt);
right.insert(l.begin() + midpt, l.end());
于 2013-08-13T21:11:55.447 回答