/*
多个有序数组合并
优先队列(小顶堆)
*/
struct node{
int value;
int out_index;//数组外索引
int in_index;//数组内索引
node(int v, int o,int i){
value = v;
out_index = o;
in_index = i;
}
bool operator<(node a)const{
return value < a.value;
}
bool operator>(node a)const{
return value > a.value;
}
};
vector<int> mergeSort(vector<vector<int>> &nums){
vector<int> res;
priority_queue <node, vector<node>,greater<node>> order;
int N = nums.size(), M = nums[0].size();
//将每个数组的第一个元素(最小)放入小顶堆
for (int k = 0; k < N; k++){
order.push(node(nums[k][0], k, 0));
}
int i = 0, j = 0;
//优先队列满,取最小元素放入数组,然后将索引改为最小元素对应的数组中的索引
while (res.size() < N*M){
node tmp = order.top();//获得优先队列中最小值元素
res.push_back(tmp.value);//存入目标数组
i = tmp.out_index;//最小值元素对应数组
j = tmp.in_index + 1;//最小值元素对应数组内下一个的元素
order.pop();
if (j == M)//达到某数组末尾
{
order.push(node(INFTY, i, j));
}
else
{
order.push(node(nums[i][j], i, j));
}
}
return res;
}
思路:
利用优先队列(即小顶堆)自动调整顺序的特点
- 将n个数组的第一个元素构建优先队列(小顶堆)
- 重复下列步骤n*m次:
- 每次从堆中取出最小元素(堆顶元素),并将其存入输出数组中
- 用堆顶元素所在数组的下一元素将堆顶元素替换掉,
- 如果数组中元素被取光了,将堆顶元素替换为无穷大。每次替换堆顶元素后,重新调整堆
参考:https://blog.csdn.net/u012328476/article/details/52522900
//验证
int arr[] = { 2,3,5,6};
int arr2[] = { 1, 4, 7, 8 };
int arr3[] = { 9, 10, 11, 12 };
int n = sizeof(arr) / sizeof(int);
vector<int> vec(arr, arr + sizeof(arr) / sizeof(int));
vector<int> vec2(arr2, arr2 + sizeof(arr2) / sizeof(int));
vector<int> vec3(arr3, arr3 + sizeof(arr3) / sizeof(int));
vector<vector<int>> Mat;
Mat.push_back(vec);
Mat.push_back(vec2);
Mat.push_back(vec3);
vector<int> ret = mergeSort(Mat);
for (int i = 0; i < ret.size(); i++)
cout << ret[i] << " ";