我假设没有库到merger。否则,您必须编写自己的linked list(这可能是转发,或normal list)。休息一样。简单示例(两个列表):
#include <list>
#include <iostream>
using namespace std;
int main(void)
{
list<int> a = { 1, 3, 5, 7, 9}, b = { 2, 4 , 6, 8, 9, 10}, c; //c is out
for(auto it1 = begin(a), it2 = begin(b); it1 != end(a) || it2 != end(b);)
if(it1 != end(a) && (it2 == end(b) || *it1 < *it2)) {
c.push_back(*it1);
++it1;
}
else {
c.push_back(*it2);
++it2;
}
for(auto x : c)
cout<<x<<' ';
cout<<'\n';
}
结果:
1 2 3 4 5 6 7 8 9 9 10
注意!您必须使用标志 -std=c++11(或其他 c++11)进行编译。例如:
g++ -std=c++11 -Wall -pedantic -Wextra -O2 d.cpp -o program.out
复杂度:Θ(n)
内存:Θ(n)
不难看出,每个元素在O(1)中只计算一次,我们有n个元素,所以它是Θ(n)。 p>
内存复杂度显而易见。值得一提的是,如果不再需要这两个列表,无需额外分配(const memory)即可完成。
算法本身已经described这么多次了,再写一遍也没意义。
在主要问题中,我们有很多序列,但想法是一样的。这里有丰富的例子:
int main(void)
{
vector<vector<int> > in{{ 1, 3, 5, 7, 9}, { 2, 4 , 6, 8, 9, 10}, {2,5,7,12,10,11,18}};
vector<int> out;
typedef tuple<int, vector<int>::iterator, vector<int>::iterator> element;
priority_queue<element, vector<element>, greater<element> > least;
for(auto& x : in) //Adding iterators to the beginning of (no empty) lists
if(!x.empty()) //and other parts of the element (value and end of vector)
least.emplace(x.front(),begin(x),end(x));
while(!least.empty()) { //Solving
auto temp = least.top(); least.pop();
out.push_back(get<0>(temp)); //Add the smallest at the end of out
++get<1>(temp);
if(get<1>(temp) != get<2>(temp)){//If this is not the end
get<0>(temp) = *get<1>(temp);
least.push(temp); //Update queue
}
}
for(const auto& x : out) //Print solution
cout<<x<<' ';
cout<<'\n';
}
复杂度:Θ(n log k)
内存:Θ(n)
pop和insert操作在O(log k)中,我们执行n次,所以是O(n log k)。
内存还是很明显的,我们在priority_queue中总是有k个元素,而O(n)在out sequence.