怎樣實現乙個按優先順序排序的佇列?並且在這個佇列上面每次 pop 操作總是返回優先順序最高的那個元素
下面的類利用 heapq 模組實現了乙個簡單的優先順序佇列:
import heapq
class
priorityqueue
:def
__init__
(self)
: self._queue =
self._index =
0def
push
(self, item, priority):(
-priority, self._index, item)
) self._index +=
1def
pop(self):[
-1]
下面是它的使用方式:
>>
>
class
item:.
..def__init__
(self, name):.
.. self.name = name..
.def
__repr__
(self):.
..return
'item()'
.format
(self.name)..
.>>
> q = priorityqueue(
)>>
> q.push(item(
'foo'),
1)>>
> q.push(item(
'bar'),
5)>>
> q.push(item(
'spam'),
4)>>
> q.push(item(
'grok'),
1)>>
> q.pop(
)item(
'bar'
)>>
> q.pop(
)item(
'spam'
)>>
> q.pop(
)item(
'foo'
)>>
> q.pop(
)item(
'grok'
)>>
>
仔細觀察可以發現,第乙個 pop() 操作返回優先順序最高的元素。
另外注意到如果兩個有著相同優先順序的元素 ( foo 和 grok )
pop 操作按照它們被插入到佇列的順序返回的。
在上面**中,佇列包含了乙個 (-priority, index, item) 的元組。優先順序為負
數的目的是使得元素按照優先順序從高到低排序。這個跟普通的按優先順序從低到高排序
的堆排序恰巧相反。
index 變數的作用是保證同等優先順序元素的正確排序。通過儲存乙個不斷增加的
index 下標變數,可以確保元素按照它們插入的順序排序。而且, index 變數也在相
同優先順序元素比較的時候起到重要作用。
為了闡明這些,先假定 item 例項是不支援排序的:
>>
> a = item(
'foo'
)>>
> b = item(
'bar'
)>>
> a < b
traceback (most recent call last)
:file ""
, line 1,in
typeerror: unorderable types: item(
)< item(
)>>
>
如果你使用元組 (priority, item) ,只要兩個元素的優先順序不同就能比較。但是
如果兩個元素優先順序一樣的話,那麼比較操作就會跟之前一樣出錯:
>>
> a =(1
, item(
'foo'))
>>
> b =(5
, item(
'bar'))
>>
> a < b
true
>>
> c =(1
, item(
'grok'))
>>
> a < c
traceback (most recent call last)
:file ""
, line 1,in
typeerror: unorderable types: item(
)< item(
)>>
>
通過引入另外的 index 變數組成三元組 (priority, index, item) ,就能很好的
避免上面的錯誤,因為不可能有兩個元素有相同的 index 值。python 在做元組比較時
候,如果前面的比較以及可以確定結果了,後面的比較操作就不會發生了:
>>
> a =(1
,0, item(
'foo'))
>>
> b =(5
,1, item(
'bar'))
>>
> c =(1
,2, item(
'grok'))
>>
> a < b
true
>>
> a < c
true
>>
>
如果你想在多個執行緒中使用同乙個佇列,那麼你需要增加適當的鎖和訊號量機制。
heapq 模組的官方文件有更詳細的例子程式以及對於堆理論及其實現的詳細說明。
1 5 實現乙個優先順序佇列
問題 怎樣實現乙個按優先順序排序的佇列?並且在這個佇列上面每次pop操作總是返回優先順序最 高的那個元素 通過引入另外的 index 變數組成三元組 priority,index,item 就能很好的避免上面 的錯誤,因為不可能有兩個元素有相同的 index 值。import heapq class...
1 5實現乙個優先順序佇列
問題 怎樣實現又給按優先順序排序的佇列?並且在佇列上面每次pop操作總是返回優先順序最高的那個元素 解決方案 下面的類利用heapq模組實現了乙個簡單的優先順序佇列 import heapq class priorityqueue def init self self.queue self.inde...
redis PHP實現的乙個優先順序去重佇列
主要思路是用乙個set做前端去重緩衝,若干個list做後端的多優先順序訊息佇列,用乙個程序來進行分發,即從set中分發訊息到佇列.set緩衝的設計為當天有效,所以有個零點問題,有可能在零點前set中剛放進去的訊息沒有分發即失效,這一點可以用另乙個程序彌補處理前一天的遺留訊息和刪除前一天的緩衝 aut...