1. 程式人生 > >基於雙端堆實現的優先順序佇列(3):外觀

基於雙端堆實現的優先順序佇列(3):外觀

   本文講述雙端堆的5個公開泛型操作演算法:make_dheap(原位構造雙端堆)、push_dheap(插入元素)、pop_max_dheap(刪除最大元素)、pop_min_dheap(刪除最小元素),is_dheap(堆驗證),每個演算法都提供<小於運算子和仿函式比較2個版本,要注意的是比較必須是嚴格弱序的,即對於<版本存在a<b為真且b<a為假;對於仿函式版本,則存在comp(a,b)為真且comp(b,a)為假。而基於雙端堆實現的優先順序佇列只是呼叫對應的泛型演算法而已。程式碼如下:
1、構造堆  1template<typename _RandIt> 2inline void make_dheap(_RandIt _first,_RandIt _last)
 3{
 4    typedef typename std::iterator_traits<_RandIt>::difference_type _Distance;
 5    typedef typename std::iterator_traits<_RandIt>::value_type _Value;
 6
 7    _Distance _len 
= _last - _first;
 8    if (2> _len) return;
 9
10    _Distance _bottom = _len -1,_half = _bottom >>1,_index,_part;
11    _index = __partner_dheap(_bottom);
12    _index > _bottom ? _index = ((_index -2>>1+1 : _index +=1;
13
14    for (;_index <= _bottom;++_index)
15    
{
16        _part = __partner_dheap(_index);
17        if (__is_max_dheap(_index))
18        {
19            if (*(_first + _index) <*(_first + _part))
20                std::swap(*(_first + _index),*(_first + _part));
21        }
22        else23        {
24            if (_part > _bottom) _part 
= (_part -2>>1;
25            if (*(_first + _part) <*(_first + _index))
26                std::swap(*(_first + _index),*(_first + _part));
27        }
28    }
29    if (0>= _half) return;
30
31    for (_index = _half -1; _index >=0--_index)
32    {    
33        __adjust_dheap(_first,_len,_index,*(_first + _index),false);
34    }
35}
36
37template<typename _RandIt,typename _Compare>38inline void make_dheap(_RandIt _first,_RandIt _last,_Compare _comp)
39{
40    typedef typename std::iterator_traits<_RandIt>::difference_type _Distance;
41    typedef typename std::iterator_traits<_RandIt>::value_type _Value;
42
43    _Distance _len = _last - _first;
44    if (2> _len) return;
45
46    _Distance _bottom = _len -1,_half = _bottom >>1,_index,_part;
47    _index = __partner_dheap(_bottom);
48    _index > _bottom ? _index = ((_index -2>>1+1 : _index +=1;
49
50    for (;_index <= _bottom;++_index)
51    {
52        _part = __partner_dheap(_index);
53        if (__is_max_dheap(_index))
54        {
55            if (_comp(*(_first + _index),*(_first + _part)))
56                std::swap(*(_first + _index),*(_first + _part));
57        }
58        else59        {
60            if (_part > _bottom) _part = (_part -2>>1;
61            if (_comp(*(_first + _part),*(_first + _index)))
62                std::swap(*(_first + _index),*(_first + _part));
63        }
64    }
65    if (0>= _half) return;
66
67    for (_index = _half -1; _index >=0--_index)
68    {    
69        __adjust_dheap(_first,_len,_index,*(_first + _index),_comp,false);
70    }
71}
   2、插入元素
 1template<typename _RandIt> 2inline void push_dheap(_RandIt _first,_RandIt _last)
 3{
 4    typedef typename std::iterator_traits<_RandIt>::difference_type _Distance;
 5    typedef typename std::iterator_traits<_RandIt>::value_type _Value;
 6
 7    _Distance _dist = _last - _first;
 8    if (2> _dist) return;
 9
10    _Value _val =*(_last -1);
11    _Distance _bottom = _dist -1, _part = __partner_dheap(_bottom);
12    if (__is_max_dheap(_bottom))
13    {
14        if (*(_first + _bottom) <*(_first + _part))
15        {
16            *(_first + _bottom) =*(_first + _part);
17            __push_min_dheap(_first,_part,(_Distance)0,_val);
18        }
19        else20        {
21            __push_max_dheap(_first,_bottom,(_Distance)1,_val);
22        }
23    }
24    else25    {
26        if (_part > _bottom) _part = (_part -2>>1
27        if (*(_first + _bottom) <*(_first + _part))
28        {
29            __push_min_dheap(_first,_bottom,(_Distance)0,_val);
30        }
31        else32        {
33            *(_first + _bottom) =*(_first + _part);
34            __push_max_dheap(_first,_part,(_Distance)1,_val);
35        }
36    }
37}
38
39template<typename _RandIt,typename _Compare>40inline void push_dheap(_RandIt _first,_RandIt _last,_Compare _comp)
41{
42    typedef typename std::iterator_traits<_RandIt>::difference_type _Distance;
43    typedef typename std::iterator_traits<_RandIt>::value_type _Value;
44
45

相關推薦

基於實現優先順序佇列3外觀

   本文講述雙端堆的5個公開泛型操作演算法:make_dheap(原位構造雙端堆)、push_dheap(插入元素)、pop_max_dheap(刪除最大元素)、pop_min_dheap(刪除最小元素),is_dheap(堆驗證),每個演算法都提供<小於運算子和仿函式比較2個版本,要注意

基於實現優先順序佇列1原理

前言    眾所周知,stl中的優先順序佇列是基於最大堆實現的,能夠在對數時間內插入元素和獲取優先順序最高的元素,但如果要求在對數時間內還能獲取優先順序最低的元素,而不只是獲取優先順序最高的元素,該怎麼實現呢?可以用最大堆-最小堆或雙端堆資料結構來實現,最大堆-最小堆和雙端堆都是支援雙端優先佇列

基於實現優先順序佇列2內幕

   在《基於雙端堆實現的優先順序佇列(1):原理》一文中講述了雙端堆的相關原理,本文則詳細講述具體的內部實現,便於區分,內部函式名稱都以雙下劃線作為字首,在這裡,有幾個關鍵問題需要說明    1)怎麼求一個結點的對稱結點:如果完全二叉樹根結點從索引1開始但不儲存元素,那麼最小堆根結點則在索引2

TensorFlow入門 LSTM 實現序列標註分詞

vsm max poc 代碼 單詞 arch 大致 雙端 fun http://blog.csdn.net/Jerr__y/article/details/70471066 歡迎轉載,但請務必註明原文出處及作者信息。 @author: huangyongye @creat_

TensorFlow入門 LSTM 實現序列標註分詞

歡迎轉載,但請務必註明原文出處及作者資訊。 @author: huangyongye @creat_date: 2017-04-19 前言 本例子主要介紹如何使用 TensorFlow 來一步一步構建雙端 LSTM 網路(聽名字就感覺好膩害的樣子),

基於Redis實現分散式訊息佇列3

1、Redis是什麼鬼? Redis是一個簡單的,高效的,分散式的,基於記憶體的快取工具。 假設好伺服器後,通過網路連線(類似資料庫),提供Key-Value式快取服務。 簡單,是Redis突出的特色。 簡單可以保證核心功能的穩定和優異。 2、效能

實現優先順序佇列 Java實現

優先順序佇列分為最大優先順序佇列和最小優先順序佇列。本文介紹基於大根堆實現最大優先順序佇列。關於堆的介紹見另一篇博文: 堆這種資料結構 Java實現 最小優先順序佇列的實現可以在本文最後給出的github地址裡找到。 最大優先順序佇列包含四個操作:

兩個棧實現一個佇列java

一、問題描述 使用兩個棧實現一個佇列 二、演算法分析 棧是先進後出,因此兩個可以模擬實現先進先出 三、演算法設計 定義資料結構 Stack<Integer> stack1 Stack<Integer> stack2 對於push操作:元素入佇列

基於Python語言使用RabbitMQ訊息佇列

釋出/訂閱 前面的教程中我們已經建立了一個工作佇列。在一個工作佇列背後的假設是每個任務恰好會傳遞給一個工人。在這一部分裡我們會做一些完全不同的東西——我們會發送訊息給多個消費者。這就是所謂的“釋出/訂閱”模式。 為了解釋這種模式,我們將會構建一個簡單的日誌系

我的WCF之旅3在WCF中實現工通訊

雙工(Duplex)模式的訊息交換方式體現在訊息交換過程中,參與的雙方均可以向對方傳送訊息。基於雙工MEP訊息交換可以看成是多個基本模式下(比如請求-回覆模式和單項模式)訊息交換的組合。雙工MEP又具有一些變體,比如典型的訂閱-釋出模式就可以看成是雙工模式的一種表現形式。雙工訊息交換模式使服務端回撥(Call

Springboot + rabbitMQ實現延遲佇列消費者

由於太長了,所以分成兩篇寫,接上一篇講解了訊息的定義和傳送,這裡繼續講解消費者 由於可能每條訊息所處理的邏輯可能不一樣,例如:常規訂單30分鐘不支付則取消訂單,團購訂單一天拼團不成功則取消等等,為了避免在消費者監聽類中使用大量if else,這裡使用策略模式來處理(由於sp

自定義連結串列3用連結串列的方式實現佇列

通過學習自定義連結串列,瞭解連結串列的資料結構。 本篇以連結串列的方式實現佇列。(參看陣列佇列   ,以及 迴圈佇列)     首先寫一個佇列的介面,描述其具有的基本功能。參看 自定義佇列:Queue.java 然後寫一個介面的實現類,

用最大堆實現優先佇列c++

關於最大堆,最小堆的概念這裡不再介紹。 #include <iostream> #include <vector> using namespace std; template<typename T> class Pri

極光訊息推送伺服器開發實現推送

以前一直使用的極光的手動輸入推送內容然後推送到客戶端,今天遇到了推送頻率比較高且比較有規律的內容,比如事實天氣。這樣就需要用我們自己的伺服器來自動生成推送內容了。 可以看到,上面兩句話很醒目,我們看看它封裝的REST API是個什麼東西,再點進去看看 上面兩句話讀了一

基於Python語言使用RabbitMQ訊息佇列

工作佇列 在第一節我們寫了程式來向命名佇列傳送和接收訊息 。在本節我們會建立一個工作佇列(Work Queue)用來在多個工人(worker)中分發時間消耗型任務(time-consuming tasks)。 工作佇列(又叫做: Task Queues)背後

Android彈幕實現基於B站彈幕開源系統3-文字彈幕的完善和細節調整

Android彈幕實現:基於B站彈幕開源系統(3)本文在附錄1,2的基礎上再次對非同步獲取彈幕並顯示彈幕完善邏輯和程式碼,集中在上層Java程式碼部分:package zhangphil.danmaku; import android.app.Activity; imp

極光訊息推送伺服器開發實現推送

前面我們已經實現了通過我們自己的伺服器生成訊息向極光訊息推送伺服器傳送推送訊息的功能,下面我們來看看如何在手機客戶端實現訊息接收。 一、在極光上建立一個測試專案 如上圖所示,下載Android Example 執行效果如圖 下面我們通過原始碼先看看上面的四行顯示Tex

資料結構3佇列的原理和實現

完整程式碼拉到最底下 一、介紹 佇列顧名思義就像我們生活中排隊一樣,先進先出。 如上圖所示,25、16、5、9依次在佇列中,按照順序拿出的資料也分別是25、26、5、9。 二、實現過程及思路 底層使用陣列來實現,實現的功能有插入資料到隊尾、移除隊首資料、檢視隊首資料、判斷佇列是否為空、判斷佇列是否存滿。

grpc3使用 golang 開發 grpc 服務和client

ava 相互調用 相互 localhost rpcclient int err pri nec 1,關於grpc-go golang 能夠能夠做grpc的服務端

用python來實現機器學習線性迴歸linear regression

需要下載一個data:auto-mpg.data 第一步:顯示資料集圖 import pandas as pd import matplotlib.pyplot as plt columns = ["mpg","cylinders","displacement","horsepowe