最大堆k路归并

本文介绍了如何设计一个时间复杂度为O(n*lgk)的算法,通过最大堆将k个已排序的链表高效地合并成一个有序链表。文章详细阐述了节点定义,并提供了按从大到小排序的代码实现。

问题:设计一个时间复杂度为O(n*lgk)的算法,它能够将k个有序链表合并为一个有序表,这里n是所有输入链表包含的总的元素个数

下面是节点Node的定义

#pragma once
class Node {
public:
    Node(int v) :value(v),next(nullptr){ }
    void setNext(Node* n) { next=n; }
    Node* getNext() { return next; }
    int getValue() { return value; }
private:
    int value;
    Node* next;
};

代码实现,按从大到小排序

#include<iostream>
#include<fstream>
#include<vector>
#include"Node.h"
using std::ifstream; using std::cout; using std::endl;
using std::vector;
int main() {
    void printHeap(const vector<Node*>& h);
    void test(Node* n);
    void buildMaxHeap(vector<Node*>& vn);
    Node* heapExtractMax(vector<Node*>& vn);
    void insertHeap(vector<Node*>& vn, Node* key);
    vector<Node*> heap;
    Node head(0); 
    Node* n1=new Node(27);   head.setNext(n1);
    n1->setNext(new Node(14)); n1 = n1->getNext();
    n1->setNext(new Node(11)); n1 = head.getNext();
    Node* n2 = new Node(35);   head.setNext(n2);
    n2->setNext(new Node(13)); n2 = n2->getNext();
    n2->setNext(new Node(2)); n2 = head.getNext();
    Node* n3 = new Node(25);   head.setNext(n3);
    n3->setNext(new Node(18)); n3 = n3->getNext();
    n3->setNext(new Node(6)); n3 = head.getNext();
    Node* n4 = new Node(37);   head.setNext(n4);
    n4->setNext(new Node(18)); n4 = n4->getNext();
    n4->setNext(new Node(1)); n4 = head.getNext();
    heap.push_back(n1); heap.push_back(n2);
    heap.push_back(n3); heap.push_back(n4);
    buildMaxHeap(heap);
    const int total_item = 12;
    head.setNext(heapExtractMax(heap));
    Node* p = head.getNext();
    insertHeap(heap, p->getNext());
    for (int i = 0;i < total_item-1;i++) {
        p->setNext(heapExtractMax(heap));
        p = p->getNext();
        if (p->getNext()) 
            insertHeap(heap, p->getNext());
    }
    p = head.getNext();
    cout << "*********The Result is************" << endl;
    test(p);
    return 0;
}
void test(Node* n) {
    while (n) {
        cout << n->getValue() << " ";
        n = n->getNext();
    }
    cout << endl;
}
size_t left(int i) { return i * 2; }
size_t right(int i) { return i * 2 + 1; }
void exchange(Node*& a, Node*& b) {
    Node* c = a;
    a = b;
    b = c;
}
void maxHeapify(vector<Node*>& vn,size_t i) {
    size_t size = vn.size();
    size_t largest;
    size_t l = left(i),r = right(i);
    if (l<=size&&vn[l-1]->getValue()>vn[i-1]->getValue())  largest = l;
    else largest = i;
    if (r<=size&&vn[r-1]->getValue()>vn[largest-1]->getValue()) largest = r;
    if (largest != i) {
        exchange(vn[i-1], vn[largest-1]);
        maxHeapify(vn, largest);
    }
}
void buildMaxHeap(vector<Node*>& vn) {
    void maxHeapify(vector<Node*>& vn, size_t i);
    auto length = vn.size();
    for (size_t i = length / 2;i >=1;i--)
        maxHeapify(vn, i);
}
Node* heapExtractMax(vector<Node*>& vn) {
    auto len = vn.size();
    if (len < 1) {
        std::cerr << "heap underflow" << endl;
        return nullptr;
    }
    auto max = vn[0];
    vn[0] = vn[len - 1];
    len -= 1;
    vn.resize(len);   //需要重新计算vn大小
    maxHeapify(vn, 1);
    return max;
}
size_t parent(int i) { return i / 2; }
void insertHeap(vector<Node*>& vn, Node* key) {
    vn.push_back(key);
    auto i = vn.size();
    while (i >1 && vn[parent(i) - 1]->getValue() <key->getValue()) {
                                         //此处需要与key->getValue()比较否则会出错
        vn[i - 1] = vn[parent(i) - 1];
        i=parent(i);
    }
    vn[i - 1] = key;
}
void printHeap(const vector<Node*>& h) {
    for (const auto i : h)
        cout << i->getValue() << " ";
    cout << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值