zoukankan      html  css  js  c++  java
  • 数据结构:优先队列 基于堆实现(python版)

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 
     4 '''
     5 Author: Minion-Xu
     6 '''
     7 
     8 #异常类
     9 class HeapPriQueueError(ValueError):
    10     pass
    11 
    12 class Heap_Pri_Queue(object):
    13     def __init__(self, elems = []):
    14         self._elems = list(elems)
    15         if self._elems:
    16             self.buildheap()
    17 
    18     #判断是否为空
    19     def is_empty(self):
    20         return self._elems is []
    21 
    22     #查看堆顶元素,即优先级最低元素
    23     def peek(self):
    24         if self.is_empty():
    25             raise HeapPriQueueError("in pop")
    26         return self._elems[0]
    27 
    28     #将新的优先级加入队列 O(logn)
    29     def enqueue(self, e):
    30         #在队列末尾创建一个空元素
    31         self._elems.append(None)
    32         self.siftup(e, len(self._elems) - 1)
    33 
    34     #新的优先级默认放在末尾,因此失去堆序,进行siftup构建堆序
    35     #将e位移到真确的位置
    36     def siftup(self, e, last):
    37         elems, i, j = self._elems, last, (last-1)//2 #j为i的父节点
    38         while i>0 and e < elems[j]:
    39             elems[i] = elems[j]
    40             i, j = j, (j-1)//2
    41         elems[i] = e
    42 
    43     #堆顶值最小优先级最高的出队,确保弹出元素后任然维持堆序
    44     #将最后的元素放在堆顶,然后进行siftdown
    45     #  O(logn)
    46     def dequeue(self):
    47         if self.is_empty():
    48             raise HeapPriQueueError("in pop")
    49         elems = self._elems
    50         e0 = elems[0]
    51         e = elems.pop()
    52         if len(elems)>0:
    53             self.siftdown(e, 0, len(elems))
    54         return e0
    55 
    56     def siftdown(self, e, begin, end):
    57         elems, i, j = self._elems, begin, begin*2 + 1
    58         while j < end:
    59             if j+1 < end and elems[j] > elems[j+1]:
    60                 j += 1
    61             if e < elems[j]:
    62                 break
    63             elems[i] = elems[j]
    64             i, j = j, j*2+1
    65         elems[i] = e
    66 
    67     #构建堆序 O(n)
    68     def buildheap(self):
    69         end = len(self._elems)
    70         for i in range(end//2, -1, -1):
    71             self.siftdown(self._elems[i], i, end)
    72 
    73 
    74 if __name__=="__main__":
    75     l = Heap_Pri_Queue([5,6,1,2,4,8,9,0,3,7])
    76     print(l._elems)
    77     #[0, 2, 1, 3, 4, 8, 9, 6, 5, 7]
    78     l.dequeue()
    79     print(l._elems)
    80     #[1, 2, 7, 3, 4, 8, 9, 6, 5]
    81     print(l.is_empty())
    82     l.enqueue(0)
    83     print(l._elems)
    84     print(l.peek())

    插入元素:末尾插入, 向上筛选(siftup)

    弹出元素:堆顶弹出, 末尾元素充当堆顶, 向下筛选(siftdown)

  • 相关阅读:
    Hadoop IO
    HDFS
    简介
    队列
    classLoader和Class.forName的区别
    String为什么是final类型的
    Fabric
    超级账本——面向企业的分布式账本
    以太坊
    pycharm破解教程
  • 原文地址:https://www.cnblogs.com/xautxuqiang/p/6129198.html
Copyright © 2011-2022 走看看