最小堆k路歸併

2021-06-22 09:26:14 字數 1504 閱讀 6006

轉至:

clrs 6.5-9

演算法思想:

1. 從k個鍊錶中取出每個鍊錶的第乙個元素,組成乙個大小為k的陣列arr,然後將陣列arr轉換為最小堆,那麼arr[0]就為最小元素了

2. 取出arr[0],將其放到新的鍊錶中,然後將arr[0]元素在原煉表中的下乙個元素補到arr[0]處,即arr[0].next,如果 arr[0].next為空,即它所在的鍊錶的元素已經取完了,那麼將堆的最後乙個元素補到arr[0]處,堆的大小自動減一,迴圈n-k次即可。

為了方便貼上,把.h和.cpp都弄在一起,首先是兩個類list和node,然後就是兩個關於最小堆操作的函式,**有點長,但是一點都不難,因為你肯定看過最大堆的操作,那麼最小堆就大同小異了:

#include

using namespace std;

class node

;class list

;//修正i的位置,在此處已經假設i的子節點都是堆

void min_heapify(node*&a, int i, int length);

//建立陣列的堆

void build_min_heap(node*&a, int length);

int main()

node* arr =new node[k];

arr[0] =*(list_one->first);

arr[1] =*(list_two->first);

arr[2] =*(list_three->first);

arr[3] =*(list_four->first);

arr[4] =*(list_five->first);

//先對這k個排序

build_min_heap(arr, k);

list* list =new list();

//每次取arr[0]的下乙個node,如果node為空的話,

//則把堆末尾的元素補到arr[0],由於有--k,所以堆的大小減一

while(k >0)

node* begin = list->first;

while(begin != null)

return 0;

}void min_heapify(node*&a, int i, int length)

if(right <= length -1&& a[right] < a[smallest])

if(smallest != temp)

else

break;}}

void build_min_heap(node*&a, int length)

node::node()

node::node(int d)

node::operator node() const

bool node::operator < (const node& temp)

list::list()

void list::insert(int d)

prev->next = node;}}

K路歸併 例題

例題傳送門 有m種商品,每一種商品有多個值,然後要從每一種商品中選出乙個值組成乙個型別,型別值為選出的商品值的sum.問前k小個的值是多少.k路歸併的典型例題,把全部進行組合,再排序輸出前k個時不可能的,因為組合達到了100 100次方個數,但是這類題的關鍵在於k不大,這裡只有100,所以每次進行兩...

演算法導論6 5 8習題解答 最小堆K路合併

演算法思想 1.從k個鍊錶中取出每個鍊錶的第乙個元素,組成乙個大小為k的陣列arr,然後將陣列arr轉換為最小堆,那麼arr 0 就為最小元素了 2.取出arr 0 將其放到新的鍊錶中,然後將arr 0 元素在原煉表中的下乙個元素補到arr 0 處,即arr 0 next,如果arr 0 next為...

k路歸併排序

題目 給定k個已序鍊錶,要求盡可能快的將這k個鍊錶合併為乙個有序鍊錶。方案1 將這k個鍊錶標號為1,2,k,對於這k個鍊錶,我們首先合併鍊錶1和鍊錶2,得到乙個有序的鍊錶l12,然後將l12和鍊錶3進行合併.直到k個鍊錶均合併完成,最終便能夠得到有序的鍊錶l1k,即為這k個鍊錶合併後的有序鍊錶。對於...