我是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);
}
答案 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());
这会直接从相应的范围构建两个新列表left
和right
。 std::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倍(尽管取决于列表大小,缓存可能会至少在某种程度上影响它。)