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

来源:互联网 发布:淘宝的ip地址怎么看 编辑:程序博客网 时间:2024/06/14 02:55

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

优先队列(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 mathclass 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 maximport mathclass 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 mathclass 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 mathclass 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)