優先佇列(priority queue)是由二叉堆(binary heap)實現的,它是一種完全二叉樹(complete binary tree)。也就是說,整棵二叉樹binary tree除了最底層的葉節點之外,是填滿的,而最底層的葉節點由左至右又不得有空隙。
完全二叉樹的這個特點,給我們實現二叉堆帶來了極大的便利:
以最大堆max-heap為例,介紹下插入與出堆操作
插入操作過程大概描述就是:
先將要插入的元素的位置(注意我們演算法每次只定位位置)定在vector的末尾,
每次將預定要插入的元素與該位置的父節點比較,如果比父節點大,將父節點移至該位置,該位置改為父節點,然後繼續重複如上操作;如果比父節點小結束操作
將要插入的元素填至要定位的位置
插入操作stl原始碼如下:
template inline void push_heap(randomaccessiterator first, randomaccessiterator last)
template inline void __push_heap_aux(randomaccessiterator first, randomaccessiterator last, distance*, t*)
// 以下這組push_back()不允許指定「大小比較標準」
template void __push_heap(randomaccessiterator first, distance holeindex, distance topindex, t value)
// 持續至頂端,或滿足heap的次序特性為止
*(first + holeindex) = value; // 令洞值為新值,完成插入操作
}
出堆操作:
將根節點與最下層最右邊的葉節點對調
將新的根節點持續下放,直到葉節點
再對這個節點執行一次percolate up(上溯)演算法(可以認為就是新增時的操作)
出堆stl原始碼如下:
template inline coid pop_heap(randomaccessiterator first, randomaccessiterator last)
template inline void __pop_heap_aux(randomaccessiterator first, randomaccessiterator last, t*)
// 以下這組 __pop_heap() 不允許指定 「大小比較標準」
template inline void __pop_heap(randomaccessiterator first, randomaccessiterator last, randomaccessiterator result, t value, distance*)
// 以下這個__adjust_heap() 不允許指定「大小比較標準」
template void __adjust_heap(randomaccessiterator first, distance holeindex, distance len, t value)
if (secondchild == len) // 沒有右子節點,只有左子節點
// 再執行一次percolate up操作以保證滿足次序特性
__push_heap(first, holeindex, topindex, value);
}
可以看出,在堆中的元素插入與極值的取得就有o(logn)的表現
stl中的優先佇列priority queue的底層就是由heap實現的
演算法導論之最大流
流網路g v,e 是乙個有向圖,其中每條邊 u,v e均有乙個非負能量c u,v 0。如果 u,v e,則假定c u,v 0。流網路中有兩個特點的頂點,源點s和匯點t,假定每個頂點均處於從源點到匯點的某條路徑上,就是說,對每個頂點v v,存在一條路徑s v t,因此圖g是連通圖,且 e v 1。設g...
網路流之最大流
網路流之最大流 一 問題引入。有n個排水口,不同的排水口之間有m條水管連線,水一開始從源點s流出,最終到達t。每條邊 水管 都有乙個最大的流量。除了s,t外,每個排水口的流入量都要等於流出量,詢問最多能有多少水到達終點t 如圖所示 即poj 1273 可以將問題進行如下整理 1 用c e 表示每條邊...
網路流之最大流
因為網上介紹網路流和最大流理論的文章非常的多,也都解釋的非常清晰並附帶 再加上繪圖技術不佳,語文表達極差,就只講解一下程式實現部分。想看理論講解及演算法正確性證明的讀者可以上網搜一搜,這裡推薦一篇部落格,鏈結如下 那麼,既然網上的資源那麼多,為什麼還要寫這篇部落格呢?一是為了湊數做筆記,二是網上的許...