1. 程式人生 > >演算法導論最小堆實現k路歸併

演算法導論最小堆實現k路歸併

問題:請給出一個時間為O(nlgk),用來將k個已排序連結串列合併為一個排序連結串列的演算法。此處的n為所有輸入連結串列中元素的總數。(提示:用一個最小堆來做k路合併)

程式設計思路:

假設k個連結串列都是非降序排列的。

(1)取k個元素建立最小堆,這k個元素分別是k個連結串列的第一個元素。建堆的時間複雜度O(k)。

(2)堆頂元素就是k個連結串列中最小的那個元素,取出它。時間複雜度O(1)。

(3)若堆頂元素所在連結串列不為空,則取下一個元素放到堆頂位置,這可能破壞了最小堆性質,所以進行堆調整。堆調整時間複雜度O(lgk)。若為空,則此子連結串列已經被合併完畢,則刪除最小堆的堆頂元素,此時最小堆的heapSize減小了1 。刪除指定元素時間複雜度O(lgk)。

重複過程2~3直到所有序列為空。

總的時間複雜度是O(k)+O(nlgk)=O(nlgk)。

相關推薦

演算法導論實現k歸併

問題:請給出一個時間為O(nlgk),用來將k個已排序連結串列合併為一個排序連結串列的演算法。此處的n為所有輸入連結串列中元素的總數。(提示:用一個最小堆來做k路合併) 程式設計思路: 假設k個連結串列都是非降序排列的。 (1)取k個元素建立最小堆,這k個元素分別是

運用並查集與實現Kruskal演算法

前言 Kruskal是在一個圖(圖論)中生成最小生成樹的演算法之一。(另外還有Prim演算法,之後會涉及到)這就牽扯到了最小生成樹的概念,其實就是總權值最小的一個連通無迴路的子圖。(結合下文的示意圖不難理解)這裡的程式碼並沒有用圖的儲存結構(如:矩陣,鄰接連結

用鄰接表和實現Dijkstra 短路演算法 (Java實現

演算法特點: 迪科斯徹演算法使用了廣度優先搜尋解決賦權有向圖或者無向圖的單源最短路徑問題,演算法最終得到一個最短路徑樹。該演算法常用於路由演算法或者作為其他圖演算法的一個子模組。 演算法的思路 Dijkstra演算法採用的是一種貪心的策略,宣告一個數

實現

題目 最小堆實現 解答 public class MinHeap { public static void main(String[] args) { int[] test = {23,42,5,1,56}; heapify(test

【劍指offer】資料流中的中位數(實現

題目描述 如何得到一個數據流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用Insert()方法讀取資料流,使用GetMedian()方法獲取當前讀取資料的中位

實現哈夫曼樹的構造及哈夫曼編碼、解碼

      以下程式的演算法思想主要來自於浙江大學陳越老師主編的資料結構一書。最大堆(最小堆思想差不多)(之後會寫一篇部落格介紹),這裡主要講講哈夫曼樹的定義及實現。 Huffman Tree 相關概念: 結點的路徑長度:從根結點到該結點的路徑上分支的數

【資料結構與演算法 minheap

最小堆與最大堆實現思路一樣,只不過順序不同,這裡只記錄最小堆。 最小堆的定義是,一棵完全二叉樹,每一個節點都大於等於其父節點。完全二叉樹是葉子都在最後一層,且儘量靠左。 實現方面可以使用連結串列或者陣列,這裡使用陣列。 如果使用陣列,那麼下標從0開始,父節點是i,則左子樹是

網路程式設計中實現的定時器

在開發Linux網路程式時,通常需要維護多個定時器,如維護客戶端心跳時間、檢查多個數據包的超時重傳等。如果採用Linux的SIGALARM訊號實現,則會帶來較大的系統開銷,且不便於管理。 本文在應用層實現了一個基於時間堆的高效能定時器,同時考慮到定時的粒度問題,

java實現優先權佇列和求大的n個數問題

堆在實現優先權佇列和求最大最小的n個數問題上,有著莫大的優勢! 對於最大堆和最小堆的定義此處不再贅述,課參考網上文章:http://blog.csdn.net/genios/article/details/8157031 本文主要是對最小堆進行實現和應用,僅供新手參考。

go利用實現優先佇列

實現程式碼 package core import "container/heap" type Item struct { Value interface{} Index

演算法導論第三版第六章 合併K個有序連結串列的三種解法(法和分治遞迴法)

題目要求是將k個有序連結串列合併為一個連結串列,時間複雜度限定為O(nlogk)。下面給出應用最小堆方法的兩個程式,最後再貼上利用分治遞迴法的程式碼,雖然時間複雜度不及堆方法,但思路相對簡單好理解。 (1)最小堆方法1 用一個大小為K的最小堆(用優先佇列+自定義降序實現)(

演算法大堆(大頂)及)的實現

此坑待埋。 下面來說一說具體演算法。 堆排序解釋第一篇(描述不太清楚) 1.堆   堆實際上是一棵完全二叉樹,其任何一非葉節點滿足性質:   Key[i]<=key[2i+1]&&Key[i]<=key[2i+2

排序()--【演算法導論

堆排序的思想在堆排序(最大堆)已做說明,故不再贅述; 總之,思想就是首先進行建堆,由於這是最小堆,故而必須保證父節點都小於孩子節點,若不滿足條件,則進行調節; 最後進行堆排序,不斷將最小的提取出來,並對剩下的進行調節,使之滿足最小堆; 故而將最大堆中的判斷父節點與孩子大小部

演算法導論第六章之大、

堆是很重要的一種資料結構,常常用在排序和優先佇列的實現上,當然在C++ STL中有優先佇列的實現,但是者並不妨礙我們去學習他。 堆其實是一種陣列物件,也就是說他的資料全部都儲存在陣列中,它可以被視為一棵完全二叉樹(不懂二叉樹的請自行百度)。(二叉堆)堆有兩種:

的構建(C++實現)--演算法拾遺(1)

現在開始想把平時遇到的零星的演算法都記錄在這個板塊裡,因為若是沒有平常的記錄而只是將曾經實現過的程式碼爛在資料夾裡的話確實不是一個很好的做法啊。畢竟這是筆記而非展示給那個平臺下的報告,所以有的時候寫的隨便一點。有時演算法具體實現上的參考出處我也會做上註釋。

找出一數中的前K個數

string nlog 浪費 art args 技術分享 str rate .net 描寫敘述: 給定一個整數數組。讓你從該數組中找出最小的K個數 思路: 最簡潔粗暴的方法就是將該數組進行排序,然後取最前面的K個數就可以。可是,本題要求的僅僅是求出最小的k個數就可以,用

c++用priority_queue實現,並求解大的n個數

輸出 return bool rand cto and gre main 最小堆 1 //c++用priority_queue實現最小堆,並求解很多數中的最大的n個數 2 #include <iostream> 3 #include <queue&

排序 大堆 Java實現

堆排序 最大堆 最小堆 Java 堆排序啊,其實是一種數據結構,二叉樹,二叉樹分為是滿二叉樹和完全二叉樹。一棵深度為 k,且有 2k - 1 個節點稱之為滿二叉樹,完全二叉樹:深度為 k,有 n 個節點的二叉樹,當且僅當其每一個節點都與深度為 k 的滿二叉樹中序號為 1 至 n 的節點對應時,

leetcode703+第k大的數字,使用

https://leetcode.com/problems/kth-largest-element-in-a-stream/description/ class KthLargest { public: int size; priority_queue<int, vec

大堆、定義及其C++程式碼實現

資料:https://blog.csdn.net/guoweimelon/article/details/50904346 但是它的最大堆刪除部分的程式碼有問題,詳見連結裡的評論區 定義 堆首先必須是一棵完全二叉樹 最大堆:完全二叉樹,父節點的值不小於子節點的值 最小堆:完全二叉樹,父節