k路归并 算法导论8-4(e)

使用STL中priority_queue(由最大最小堆实现的)来实现。注意传递参数的时候需要传递三个。

模板声明:priority_queue<Type, Container, Functional>

这里的实现要求输入完全正确,所以代码移植性非常差。

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;

typedef struct {
    int key;
    int next;
}Likelist;

bool CompareLikelist(Likelist &i1,Likelist &i2){
    return i1.key > i2.key;
}

void K_Merge(int *a,int *b, int n, int k){
    priority_queue<Likelist,vector<Likelist>,decltype(CompareLikelist) *> pq(CompareLikelist);
    for (int i = 0; i < k; i++){
        if (i > n - 1)
            pq.push({ INT_MAX, 0 });
        else pq.push({ a[i], i + k });
    }
    for (int i = 0; i < n; ++i){
        Likelist temp = pq.top();
        b[i] = temp.key;
        pq.pop();
        if (temp.next>n - 1)
            pq.push({ INT_MAX, 0 });
        else pq.push({ a[temp.next], temp.next + k });
    }
}

int main(){
    int a[10] = { 33,1, 8, 45, 2, 9, 67, 10,9, 666 };
    int b[10];
    K_Merge(a, b, 10, 3);
    for (auto r : b)
        cout << r << " ";
}
时间: 2024-08-29 16:31:57

k路归并 算法导论8-4(e)的相关文章

算法导论 6.5.9 堆实现K路归并问题

问题: 设计一个时间复杂度为O(NlogK)的算法,它能够将K个有序链表合并为一个有序链表,这里的N为所有输入链表包含的总的元素个数 分析: 该问题为经典的利用堆完成K路归并的问题: 当K个序列满足一定的条件(如单调不减或单调不增)时,利用堆实现K路归并使其归并为一个满足相同条件的 序列,具体做法如下: 1)假设存在K个序列,从每一个序列中取出一个元素放于堆中; 2)从堆中取出顶端元素,并在该元素的序列中取出下一个元素插入堆中. 3)重复操作1)与2),直到完成归并. 具体问题: poj_205

Merge k Sorted Lists, k路归并

import java.util.Arrays; import java.util.List; import java.util.PriorityQueue; /* class ListNode { ListNode next; int val; ListNode(int x) { val = x; } } */ //k路归并问题 public class MergKSortedLists { //二路归并,这个算法时间复杂度o(2n) public ListNode mergeTwoLists

POJ 2442-Sequence(heap+k路归并)

Sequence Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 7447   Accepted: 2451 Description Given m sequences, each contains n non-negative integer. Now we may select one number from each sequence to form a sequence with m integers. It's

【二叉堆】k路归并问题(BSOJ1941)

Description 有n个函数,分别为F1,F2,...,Fn.定义Fi(x)=Ai*x^2+Bi*x+Ci(x∈N*).给定这些Ai.Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个). Input 第一行输入两个正整数n和m.以下n行每行三个正整数,其中第i行的三个数分别位Ai.Bi和Ci.Ai<=10,Bi<=100,Ci<=10 000. Output 输出将这n个函数所有可以生成的函数值排序后的前m个元素.这m个数应该输出到一行,用空格隔开. Sam

POJ-2442 Sequence (K路归并问题拓展)

题意:有n行含m个元素序列,从每行取一个数得到他们的和,一共可以得到m^n个和.输出前n个最小的和. 思路:可以用优先队列递归解决,当只取前两行的数,得到两个数的和的前n小的序列.这个序列就相当于把第一行和第二行合并,再解决n-1行的子问题. 用优先队列解决的时候也有点小技巧,类似尺取法. //236 KB 563 ms C++ 1480 B #include<cstdio> #include<iostream> #include<cstring> #include&l

算法:归并算法的递归与非递归形式

归并算法是将两个或两个以上的有序表组合成一个新的有序表,它的原理是:假设初始序列含有n个记录,则可以看成是n个有序子序列,两两归并,得到[n/2]个有序子序列,再次归并--不断重复直至归并到长度为n的有序序列,这样的排序方法称为2路归并排序. 实例一:递归形式的2路归并算法 #define MAXSIZE 4 int data[MAXSIZE] = {2,1,0,3}; /* * 功能:将from数组min到max-1下标数据排好序,最后的结果是to[min]...to[max-1] * 输入:

算法导论——lec 11 动态规划及应用

和分治法一样,动态规划也是通过组合子问题的解而解决整个问题的.分治法是指将问题划分为一个一个独立的子问题,递归地求解各个子问题然后合并子问题的解而得到原问题的解.与此不同,动态规划适用于子问题不是相互独立的情况,即各个子问题包含公共的子子问题.在这种情况下,如果用分治法会多做许多不必要的工作,重复求解相同的子子问题.而动态规划将每个子问题的解求解的结果放在一张表中,避免了重复求解. 一. 动态规划介绍 1. 动态规划方法介绍: 动态规划主要应用于最优化问题, 而这些问题通常有很多可行解,而我们希

算法导论第六章优先队列(二)

优先队列可以说是堆的一个非常重要的应用,和堆对应,优先队列也分最小优先队列和最大优先队列. 优先队列是一种用来维护由一组元素构成的集合S的数据结构,其中每一个元素都有一个关键字(key),关键字赋予了一个元素的优先级,故名为优先队列.之所以用堆来实现优先队列,我想最大的原因是堆很容易对元素按关键字进行排序. 优先队列的应用: 最大优先队列:其中最为典型的就是“共享计算机系统的作业调度”,通过记录各个作业的优先级,来调度一个作业的执行.删除和插入等操作. 最小优先队列:可以被用于“基于事件驱动的模

[算法导论 Ch9 中位数和顺序统计量] Selection in O(n)

1. 寻找第k大(小)的数 假设数据存储在数组a[1..n]中 首先,寻找一个数组中最大或者最小的数,因为最大(小)的数一定要比其他所有的数大(小),因此至少要比较完所有的pair才能确定,所以时间复杂度在O(n).那么寻找第k大(小)呢? 比较直观的,就是对数组中国所有的数据先进行排序,在我们这种渣渣的计算机入门选手而言,可选的有QuickSort,MergeSort和HeapSort,甚至是ShellSort等一些比较高级的方法啊...一般的代价都在O(n*logn)上,然后直接取出即可.