python数据结构——优先级队列

前言

这里,我们的优先级队列是涉及到了一个key-value对的,其中key是我们的优先级,value是对象。

首先介绍一下优先级队列吧,是一个应用范围比队列广很多的数据结构,其实用堆来做比较好,这部分介绍的是双向链表。
如果对双向链表有问题,看这里

基本结构

首先给出一个基类

class PriorityQueueBase():
    """Abstract base class for a priority queue"""
    class _Item():
        """lightweight composite to store priority queue items"""
        __slots__ = '_key', '_value'
        def __init__(self,k,v):
            self._key = k
            self._value = v
        def __lt__(self,other):
            # 这样就可以直接比较两个结点,而不需要比较key
            return self._key < other._key
    def is_empty(self):
        """retrun True if the priority queue is empty"""
        return len(self)==0

很简单,内部有一个item的类存储每一个结点key、value,并重载了大小比较运算符,方便我们就行比较。
还有一个is_empty函数,都是常用的。

具体实现

这里的实现分为两种,排序列表和未排序列表。
顾名思义,就是我们存储的列表(其实是双向链表)是否有序,如果是无序列表,查找为O(n);如果有序,插入为O(n)。

直接贴代码,加上注释没什么问题:

# 未排序列表,查找删除代价大
class UnsortedPriorityQueue(PriorityQueueBase):
    """a min-oriented priority queue implemented with an unsorted list"""
    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"""
        # 双向链表的一个尾插法
        self._data.add_last(self._Item(key,value))
    def _find_min(self):
        """rturn 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)
        # 最小的初始为第一个,然后遍历(通过walk)
        while walk is not None:
            if walk.element() < small.element():
                small = walk
            walk = self._data.after(walk)
        return small
    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__(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"""
        newest = self._Item(key,value)
        walk = self._data.last()
        # 有序,插入比较麻烦
        while walk is not None and newest < walk.element():
            walk = self._data.before(walk)
        if walk is None:
            self._data.add_first(newest)
        else:
            self._data.add_after(walk,newest)
    def min(self):
        """return but noe remove (k,v) tuple with minimum key"""
        if self.is_empty():
            raise Empty('Priority queue is empty')
        p = self._data.first()
        item = p.element()
        return (item._key,item._value)
    def remove_min(self):
        """return and remove (k,v) with minimum key"""
        if self.is_empty():
            raise Empty('Priority queue is empty')
        item = self._data.delete(self._data.first())
        return (item._key,item._value)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值