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

235

被折叠的 条评论
为什么被折叠?



