优先级队列的抽象数据类型
这是一个包含优先级元素的集合,这个集合允许插入任意的元素,并允许删除拥有最高优先级的元素。当一个元素被插入优先级队列时,通过提供一个关联键来为该元素赋予一定的优先级。键值最小的元素将是下一个从队列中移除的元素。
一、 优先级队列的抽象数据类型的实现
形式化地将一格元素和它的优先级用一个key-value 对进行建模。在优先级队列 P 上定义优先级队列 ADT,以支持以下方法
- P.add(k, v): 向优先级队列 P 中插入一个拥有键 k 和值 v 的元组
- P.min(): 返回一个优先级队列 P 中拥有最小键值和元组(k, v);如果队列为空,将发生错误
- P.remove_min(): 从优先级队列 P中移除一个拥有最小键值的元组,并且返回这个被移除的元组;如果队列为空,将发生错误
- P.is_empty(): 如果优先级队列不包含任何元组,将返回True
- len§: 返回优先级队列中元组的数量
二、优先级队列的实现
- 组合设计模式
使用组合设计模式来存储内部元组,该元组包含键 k 和值 v 构成的键值对。为了在所有优先级队列中实现这种概念。定义一个PriorityQueueBase类,其中包含一个 _Item 嵌套类。对于元组实例 a 和 b , 基于键定义了语法 a < b
class PriorityQueueBase:
""" Abstract base class for priority queue"""
class _Item:
""" Lightweight composite to store priority queue items."""
def __init__(self, k, v):
self._key = k
self._value = v
def __lt__(self, other):
return self._key < other._key
def is_empty():
""" Return True if the priority queeu is empty. """
return len(self) == 0
- 使用未排序列表实现优先级队列
当 min 或 remove_min 方法被调用时,必须定位键值最小的元组,由于元组没有被排序,必须间检查所有元组才能找到键值最小的元组,因此定义 一个非共有的方法 _find_min,用于返回键值最小的元组的位置
class UnsortedPriorityQueue(PriorityQueueBase):
""" A min-oriented priority queue implemented with an unsorted list."""
def _find_min(self): # nonpublic utility
""" Return Position of item with minimum key."""
if self.is_empty()
raise Empty('Priority queue is empty')
small = self._data.first()
walk = self._data.after(small)
while walk is not None:
if walk.element() < small.element():
small = walk
walk = self._data.after(walk)
return small
def __init__(self):
""" Create a new empty Priority Queue."""
self._data = PositionalList()
def __len__(self):
""" Return the number of items in the priority queue."""
return len(self._data)
def add(self, key ,value):
""" Add a key-value pair."""
def min(self):
""" Return but do not remove(k,v) tuple with minimum key"""
p = self._find_min()
item = p.element()
return (item._key, item._value)
def remove_min(self):
""" Remove and return (k,v) tuple with minimum key."""
p = self._find_min()
item = self._data_delete(p)
return (item_key, item_value)
- 使用排序列表实现优先级队列
优先级队列依然采用位置列表,但列表中的元组以键值非递减的顺序进行排序,保证列表的第一个元组是拥有最小键值的元组
class SortedPriorityQueue(PriorityQueueBase):
""" A min-oriented priority queue implemented with a sorted list."""
def __init__():
""" Create a new empty Priority Queue."""
self._data = PositionalList()
def __len__():
""" Return the numbers of items in the priority queue."""
return len(self._data)
def add(self, key, value):
""" Add a key-value pair."""
newest = self._item(key, value)
walk = self._data.last()
while walk is not None and newest < walk.element():
walk = self._data.before
if walk is None:
self._data.add_first(newest)
else:
self._data.add_after(walk, newest)
def min(self):
""" Return but do not remove (k,v) tuple with minimum key."""
if self.is_empty:
rasie Empty('Priority queue is empty.')
p = self._data.first()
item = p.element()
return (item._key, item._value)
def remove_min(self):
""" Remove and return (k,v) tuple with minimum key."""
if self.is_empty():
rasie Empty('Priority queue is empty.')
item = self._data.delete(self._data.first())
return (item._key, item._value)