数据结构之优先队列:优先队列的介绍与基础操作实现,Python代码实现——14

优先队列(Priority queue)的介绍
  • 优先队列是计算机中一种抽象的数据结构类,它有着一个类似和队列或者堆的结构,但是其中每个元素额外有一个优先级别
  • 在一个优先队列中,一个高优先顺序的元素会先执行与低优先顺序的元素。在它的执行过程中,如果两个元素拥有相同的优先顺序,则会根据他们进入队列的先后顺序来确定执行先后,但是在在其他类型的数据结构中,如果两个元素优先级别相同,则不会定义这两个元素的先后执行顺序
  • 优先队列一般使用堆来进行实现,但他们在概念上与堆是有区别的。一个优先队列它可以是一个“列表”,也可以是一个“字典”,正如一个列表可以使用链表或者数组来实现一样,优先队列可以用堆或者其他各种不同的方法,如无序数组来实现
    在这里插入图片描述
要实现的两种优先队列

两种优先队列:

  1. 最大优先队列(Max priority queue),最大优先级的元素在队列最前面,可以指定最大元素取出和删除
  2. 最小优先队列(Max priority queue),最小优先级的元素在队列最前面,可以指定最小元素取出和删除
使用堆(数组)实现最大优先队列

定义方法

  1. size()获取队列大小
  2. less(x, y)对传入的两个索引对应当前队列的元素进行大小比较
  3. is_empty()判断队列是否为空
  4. swap(i, j)对传入的两个索引对应当前队列中的元素进行值交换
  5. append(item)在队列末尾添加指定元素
  6. extract_max()取出并删除最大优先级的元素
  7. sink()使用下沉排序操作,对删除元素后的队列进行排序
  8. swim()使用上浮排序操作,对从尾部插入元素的队列进行排序
最大优先队列Python代码实现
class MaxPriorityQueue:
    def __init__(self):
        self.heap = [None]
        self.N = 0

    def size(self):
        return self.N

    def less(self, i, j):
        return self.heap[i] < self.heap[j]

    def is_empty(self):
        return self.N == 0

    def swap(self, i, j):
        self.heap[i], self.heap[j] = self.heap[j], self.heap[i]

    def append(self, item):
        self.heap.append(item)
        self.N += 1
        self.swim(self.N)

    def extract_max(self):
        if self.N < 1:
            return
        first = self.heap[1]
        # print(f"first: {first}")
        self.swap(1, self.N)
        del self.heap[self.N]
        self.N -= 1
        self.sink(1, self.N)
        return first

    def sink(self, index, _range):
        while 2*index <= _range:
            max_index = 2*index if 2*index+1 > _range else \
                (2*index+1 if self.less(2*index, 2*index+1) else 2*index)
            if self.less(max_index, index):
                break
            self.swap(max_index, index)
            index = max_index

    def swim(self, index):
        while index > 1:
            if self.less(int(index/2), index):
                self.swap(int(index/2), index)
            index = int(index/2)


if __name__ == '__main__':
    MPQ = MaxPriorityQueue()

    MPQ.append('A')
    MPQ.append('B')
    MPQ.append('C')
    MPQ.append('D')
    MPQ.append('E')
    MPQ.append('F')
    MPQ.append('G')

    while not MPQ.is_empty():
        _max = MPQ.extract_max()
        print(_max, end=' ')
Max Priority Queue运行测试结果
G F E D C B A 

进行尾部插入元素操作时从小到大附加到队列,依次抽离最大元素是从大到小返回结果

使用堆(数组)实现最小优先队列

核心方法与最大优先队列实习的实现是差不多的,只是在父结点与子结点排序比较时,将两者位置调换,再进行比较和位置移动操作

最小优先队列Python代码实现
import operator


class MinPriorityQueue:
    def __init__(self):
        self.heap = [None]
        self.N = 0

    def size(self):
        return self.N

    def is_empty(self):
        return self.N == 0

    def less(self, i, j):
        return operator.lt(self.heap[i], self.heap[j])

    def swap(self, i, j):
        self.heap[i], self.heap[j] = self.heap[j], self.heap[i]

    def append(self, item):
        self.heap.append(item)
        self.N += 1
        self.swim(self.N)

    def extract_min(self):
        if self.N < 1:
            return
        _min = self.heap[1]
        self.swap(1, self.N)
        del self.heap[self.N]
        self.N -= 1
        self.sink(1, self.N)
        return _min

    def swim(self, index):
        while index > 1:
            if self.less(index, int(index / 2)):
                self.swap(index, int(index / 2))
            index = int(index / 2)

    def sink(self, index, _range):
        while 2 * index <= _range:
            min_index = 2 * index if 2 * index + 1 > _range else \
                (2 * index if self.less(2 * index, 2 * index + 1) else 2 * index + 1)
            if self.less(index, min_index):
                break
            self.swap(index, min_index)
            index = min_index


if __name__ == '__main__':
    MPQ = MinPriorityQueue()

    MPQ.append('G')
    MPQ.append('F')
    MPQ.append('E')
    MPQ.append('D')
    MPQ.append('C')
    MPQ.append('B')
    MPQ.append('A')

    while not MPQ.is_empty():
        _min = MPQ.extract_min()
        print(_min, end=' ')
Min Priority Queue运行测试结果
A B C D E F G 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值