算法导论程序12--优先队列(Python)

我们首先关注如何基于最大堆实现最大优先队列:

优先队列(priority queue)是一种用来维护一组元素构成的集合S的数据结构,其中的每一个元素都有一个相关的值,称为关键字(key)。

一个最大优先队列支持以下操作:

INSERT(S,x):把元素x插入集合S中,这一操作等价于S=S U {x}

MAXIMUM(S):返回S中具有最大关键字的元素。

EXTRACT-MAX(S):去掉并返回S中具有最大关键字的元素。

INCREASE-KEY(S,x,k):将元素x的关键字增加到k,这里假设k的值不小于x的原关键字值。


(1)MAXIMUM(S)

def heap_maximum(A):
    return A[0];

import math
class heapsort:
    def __init__(self,a_A):
        self.list=a_A
        self.heap_size = len(a_A)
    def parent(self,i):
        return math.floor((i-1)/2)
    def left(self,i):
        return 2*i+1
    def right(self,i):
        return 2*i+2
    def max_heapify(self,A,i):
        largest = i
        key = A[i]
        l = self.left(i)
        r = self.right(i)
        if l<len(A) and A[l] > A[largest]:
            largest = 2*i+1
        if r<len(A) and A[r] > A[largest]:
            largest = 2*i+2
        A[i]=A[largest]
        A[largest]=key
        if largest != i:
            self.max_heapify(A,largest)
        return A
    def build_max_heap(self,A):
        N = math.floor(len(A)/2)-1
        for i in range(N,-1,-1):
            A = self.max_heapify(A,i)
        return A

运行结果:

>>> A=[4,1,3,2,16,9,10,14,8,7]
>>> p=heapsort(A)
>>> A=p.build_max_heap(A)
>>> A
[16, 14, 10, 8, 7, 9, 3, 2, 4, 1]
>>> heap_maximum(A)
16

时间复杂度O(1)

(2)EXTRACT-MAX(S)
def heap_extract_max(A):
    if len(A)<1:
        error("heap underflow")
    max=A[0]
    A[0]=A[len(A)-1]
    heap_size=len(A)
    p=heapsort(A,heap_size)
    heap_size-=1  
    p.max_heapify(heap_size,A,1)
    return max



import math
class heapsort:
    def __init__(self,a_A,a_heap_size):
        self.list=a_A
        self.heap_size = a_heap_size
    def parent(self,i):
        return math.floor((i-1)/2)
    def left(self,i):
        return 2*i+1
    def right(self,i):
        return 2*i+2
    def max_heapify(self,heap_size,A,i):
        largest = i
        key = A[i]
        l = self.left(i)
        r = self.right(i)
        if l<heap_size and A[l] > A[largest]:
            largest = 2*i+1
        if r<heap_size and A[r] > A[largest]:
            largest = 2*i+2
        A[i]=A[largest]
        A[largest]=key
        if largest != i:
            self.max_heapify(heap_size,A,largest)
        return A
    def build_max_heap(self,A):
        N = math.floor(len(A)/2)-1
        heap_size=len(A)
        for i in range(N,-1,-1):
            A = self.max_heapify(heap_size,A,i)
        return A
    def heapsort(self,A):
        self.build_max_heap(A)
        heap_size=len(A)
        for i in range(len(A)-1,0,-1):
            temp = A[0]
            A[0] = A[i]
            A[i] = temp
            heap_size-=1
            self.max_heapify(heap_size,A,0)
            print(i,A)

运行:

>>> A=[4,1,3,2,16,9,10,14,8,7]
>>> p=heapsort(A,10)
>>> A=p.build_max_heap(A)
>>> heap_extract_max(A)
16
>>> A
[1, 14, 10, 8, 7, 9, 3, 2, 4, 1]
时间复杂度:O(lgn)
(3)INCREASE-KEY(S,x,k)

def heap_increase_key(A,i,key):
    if key < A[i]:
        error("new key is smaller than current key")
    A[i]=key
    heap_size=len(A)
    p=heapsort(A,heap_size)
    while i>0 and A[p.parent(i)]<A[i]:
        t = A[i]
        A[i]=A[p.parent(i)]
        A[p.parent(i)]=t
        i=p.parent(i)




import math
class heapsort:
    def __init__(self,a_A,a_heap_size):
        self.list=a_A
        self.heap_size = a_heap_size
    def parent(self,i):
        return math.floor((i-1)/2)
    def left(self,i):
        return 2*i+1
    def right(self,i):
        return 2*i+2
    def max_heapify(self,heap_size,A,i):
        largest = i
        key = A[i]
        l = self.left(i)
        r = self.right(i)
        if l<heap_size and A[l] > A[largest]:
            largest = 2*i+1
        if r<heap_size and A[r] > A[largest]:
            largest = 2*i+2
        A[i]=A[largest]
        A[largest]=key
        if largest != i:
            self.max_heapify(heap_size,A,largest)
        return A
    def build_max_heap(self,A):
        N = math.floor(len(A)/2)-1
        heap_size=len(A)
        for i in range(N,-1,-1):
            A = self.max_heapify(heap_size,A,i)
        return A
    def heapsort(self,A):
        self.build_max_heap(A)
        heap_size=len(A)
        for i in range(len(A)-1,0,-1):
            temp = A[0]
            A[0] = A[i]
            A[i] = temp
            heap_size-=1
            self.max_heapify(heap_size,A,0)
            print(i,A)
运行结果:

>>> A=[4,1,3,2,16,9,10,14,8,7]
>>> p=heapsort(A,10)
>>> A=p.build_max_heap(A)
>>> A
[16, 14, 10, 8, 7, 9, 3, 2, 4, 1]
>>> heap_increase_key(A,8,15)
>>> A
[16, 15, 10, 14, 7, 9, 3, 2, 8, 1]
时间复杂度:O(lgn) 关键字更新的结点到根结点的路径长度为lgn.


(4)INSERT(S,x)

def heap_increase_key(A,i,key):
    if key < A[i]:
        error("new key is smaller than current key")
    A[i]=key
    heap_size=len(A)
    p=heapsort(A,heap_size)
    while i>0 and A[p.parent(i)]<A[i]:
        t = A[i]
        A[i]=A[p.parent(i)]
        A[p.parent(i)]=t
        i=p.parent(i)


def max_heap_insert(A,key):
    A.append(float("-inf"))
    heap_increase_key(A,len(A)-1,key)


import math
class heapsort:
    def __init__(self,a_A,a_heap_size):
        self.list=a_A
        self.heap_size = a_heap_size
    def parent(self,i):
        return math.floor((i-1)/2)
    def left(self,i):
        return 2*i+1
    def right(self,i):
        return 2*i+2
    def max_heapify(self,heap_size,A,i):
        largest = i
        key = A[i]
        l = self.left(i)
        r = self.right(i)
        if l<heap_size and A[l] > A[largest]:
            largest = 2*i+1
        if r<heap_size and A[r] > A[largest]:
            largest = 2*i+2
        A[i]=A[largest]
        A[largest]=key
        if largest != i:
            self.max_heapify(heap_size,A,largest)
        return A
    def build_max_heap(self,A):
        N = math.floor(len(A)/2)-1
        heap_size=len(A)
        for i in range(N,-1,-1):
            A = self.max_heapify(heap_size,A,i)
        return A
    def heapsort(self,A):
        self.build_max_heap(A)
        heap_size=len(A)
        for i in range(len(A)-1,0,-1):
            temp = A[0]
            A[0] = A[i]
            A[i] = temp
            heap_size-=1
            self.max_heapify(heap_size,A,0)
            print(i,A)
运行结果:

>>> A=[4,1,3,2,16,9,10,14,8,7]
>>> p=heapsort(A,10)
>>> A=p.build_max_heap(A)
>>> max_heap_insert(A,13)
>>> A
[16, 14, 10, 8, 13, 9, 3, 2, 4, 1, 7]

时间复杂度:O(lgn)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值