树(一),优先级队列

2020/05/17 Python Data Structure 共 1432 字,约 5 分钟

以堆来实现优先级队列,堆其实是特殊的完全二叉树。堆中的每个父节点都是要大于等于或者小于等于它的孩子节点

列表与优先级队列

列表

  • 列表中存储的元素是乱序的,插入的时间复杂度为1,取最值的时间复杂度为O(n)

  • 列表中存储的元素是有序的,插入的时间复杂度为O(n),取最值的时间复杂度为1

优先级队列

  • 优先级队列插入的时间复杂度为O(log(n)),取最值的时间复杂度为1

代码

class MaxHeap:
    """
    最大堆:索引第一位优先级最高
    """

    def __init__(self):
        self.data = []
        self.count = -1

    def add(self, priority, value):
        self.data.append((priority, value))
        self.count += 1
        self.siftup(self.count)  # 向上堆排序

    def extract(self):
        if self.count == -1:
            raise Exception("堆为空!")
        elif self.count == 0:
            self.count -= 1
            return self.data[0]
        else:
            value = self.data[0]
            self.data[0] = self.data[self.count]  # 最右下节点值放到root
            self.count -= 1
            self.data.pop()  # 删除最右下节点
            self.siftdown(0)  # 向下堆排序
            return value

    def siftup(self, index):
        if index != 0:
            parent = int((index - 1) / 2)
            if self.data[index] > self.data[parent]:
                self.data[index], self.data[parent] = self.data[parent], self.data[index]
            self.siftup(parent)

    def siftdown(self, index):
        left = index * 2 + 1
        right = index * 2 + 2
        if left < len(self.data):
            big = left
            if right < len(self.data):
                if self.data[left] < self.data[right]:
                    big = right
            if self.data[index] < self.data[big]:
                self.data[index], self.data[big] = self.data[big], self.data[index]
                self.siftdown(big)


class PriorityQueue:
    def __init__(self):
        self._MaxHeap = MaxHeap()

    def push(self, priority, value):
        self._MaxHeap.add(priority, value)

    def pop(self):
        return self._MaxHeap.extract()


def test_priority_queue():
    pq = PriorityQueue()
    pq.push(10, 'a')
    pq.push(6, 'b')
    pq.push(7, 'c')
    pq.push(3, 'd')
    print(pq.pop())
    print(pq.pop())
    print(pq.pop())
    print(pq.pop())


if __name__ == "__main__":
    test_priority_queue()

文档信息

Search

    Table of Contents