keyedpriorityqueue
來儲存已分配的「記憶體塊」,使用priorityqueue
現在,就開始行動吧。
首先,需要乙個介面,用來獲取鍵以及獲取和設定值,如下所示:
namespace skyiv.util接著,就是我們的帶鍵值的優先佇列keyedpriorityqueue登場了:}
using system;上述using system.collections.generic;
namespace skyiv.util
public keyedpriorityqueue(ikeyvalue kv) : this(null, kv)
public keyedpriorityqueue(int capacity, ikeyvalue kv) : this(capacity, null, kv)
public keyedpriorityqueue(icomparer comparer, ikeyvalue kv) : this(16, comparer, kv)
public keyedpriorityqueue(int capacity, icomparer comparer, ikeyvalue kver)
public bool containskey(k key)
public void update(t v)
public void push(t v)
public t pop()
public t top()
void siftup(int n)
void siftdown(int n)
heap[haskey ? (keys[kver.getkey(v)] = n) : n] = v;
}}}
keyedpriorityqueue
類中,t
是要儲存在這個帶鍵值的優先佇列中的資料的型別,k
是鍵的資料型別,v
是值的資料型別。
dictionary
int> keys字段用於儲存鍵(k)在堆(heap)中的索引。
bool containskey(k key)
方法用於查詢指定的鍵是否在該優先佇列中。
update(t v)
方法用於更新指定專案的值。注意,如果要使用這個方法的話,t
不能是值型別。之所以在這個方法的第二行:
if (typeof(t).isvaluetype) throw new
invalidoperationexception("t 不能是值型別");
進行這個判斷,而不是在將該類宣告為:
class
keyedpriorityqueue
where t : class
這是因為,如果不需要呼叫update(t v)
方法的話,t
還是允許是值型別的。
該類的其他方面,除了加入對 keys 欄位的處理以外,就和標準的優先佇列差不多了。
有了這個keyedpriorityqueue
類,就可以從中派生出priorityqueue
類來:
class對於priorityqueue : keyedpriorityqueue
object, object>
public priorityqueue(int capacity) : base(capacity, null)
public priorityqueue(icomparer comparer) : base(comparer, null)
public priorityqueue(int capacity, icomparer comparer) : base(capacity, comparer, null)
}
priorityqueue
類的例項,如果呼叫containskey
方法,總是返回false
。如果呼叫update
方法,總是引發notsupportedexception
異常。
首先,block
必須從結構改為類,如下所示:
sealed class然後,需要乙個實現block
public int time
public block(int id, int time)
}
ikeyvalue
介面的類:
sealed class最後,就剩下最簡單的工作了,將 main 方法的第二行:idtime : ikeyvalue
public int getvalue(block x)
public void setvalue(block x, int v)
}
var used = new
keyedpriorityqueue(new
timecomparer());
修改為:
var used = new
keyedpriorityqueue
(new
timecomparer(), new
idtime());
就可以了。
當然,這也是有代價的,就是執行時間和記憶體使用都增加了:
iddate
author
problem
language
judgement
result
execution
time
memory
used
2568007
21:22:09 18 apr 2009
skyivben
1037
c#accepted
0.406
6 129 kb
2566773
09:24:17 18 apr 2009
skyivben
1037
c#accepted
0.265
4 521 kb
實際上,雖然keyedpriorityqueue
類中的**與priorityqueue
類中**有大量的重複,可以用本篇隨筆的方法將keyedpriorityqueue
類改為keyedpriorityqueue
泛型類,再從中派生出priorityqueue
類來,以消除重複的**。但是,這樣必然造成priorityqueue
類的執行效率降低。所以,一般情況下,priorityqueue
類還是使用原來的**為好。
當然,如果能夠從priorityqueue
類派生出keyedpriorityqueue
類,那就比較完美了。不知各位大俠是否還有更好的方法?
利用redis實現帶優先順序的訊息佇列
以前一直有使用celery的優先順序機制 基於redis的任務佇列 一直很好奇它的實現機制,在查閱了部分資料後,決定寫這篇文章,作為總結。使用sorted set 做優先順序佇列最大的優點是直觀明了。zadd key score member score member score member sc...
C 實現優先佇列的簡單例項
c 實現優先佇列的簡單例項 優先佇列類模版實現 buildmaxheap.h標頭檔案 include using namespace std define left i i 2 1 define right i i 2 2 define parent i i 1 2 void max heapify...
容易理解的python用佇列實現廣度優先遍歷檔案
需求簡單介紹 硬碟中查詢檔案,不同目錄中檔案的整合,專案開發中多檔案聯合查詢,等都要用到檔案遍歷。首先簡單闡述一下廣度遍歷實現方式 廣度遍歷檔案很明顯,每一次遍歷不追求遍歷目錄的深度,只追求其廣度。下面畫張圖形容一下 看圖分析 對 廣度遍歷測試 這個資料夾,進行遍歷,第一次把a中的東西遍歷完,資料夾...