k路归并排序
-
问题: 给定k个升序的序列,将这些序列升序排列。
-
解法:使用堆排序,首先讲k个序列中第一个元素放到小根堆中,然后每次取出堆顶元素,然后将该元素所在序列的后一个元素放到堆中,直到堆中没有元素位置。
-
输入:第一行一个数表示序列个数k,后面有 2 × k 2 \times k 2×k 行,每两行表示一个序列,第一个行表示这个序列元素个数,第二行是这个序列。如下是一个输入例子:
3
4
5 9 12 18
3
1 6 11
5
2 3 15 21 25
- C++代码:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
typedef vector<int> VI;
const int N = 110; // 最多100路
int k;
vector<int> a[N];
int main() {
cin >> k;
for (int i = 0; i < k; i++) {
int n;
cin >> n;
for (int j = 0; j < n; j++) {
int x;
cin >> x;
a[i].push_back(x);
}
}
// k路归并,堆中元素是三元组:(数据, 在第几个序列中, 是该序列中第几个元素)
vector<int> res;
priority_queue<VI, vector<VI>, greater<VI>> heap;
for (int i = 0; i < k; i++) heap.push({a[i][0], i, 0});
while (heap.size()) {
auto t = heap.top();
heap.pop();
int x = t[0], i = t[1], j = t[2];
res.push_back(x);
if (j + 1 < a[i].size()) heap.push({a[i][j + 1], i, j + 1});
}
for (auto x : res) {
cout << x << ' ';
}
return 0;
}