概念

普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。
image.png
image.png

优先队列的实现

通常采用堆数据结构来实现。

image.png

堆的定义

堆其实就是一棵完全二叉树(若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边),
定义为:具有n个元素的序列(h1,h2,…hn),当且仅当满足(hi>=h2i,hi>=h2i+1)或(hi<=h2i,hi<=2i+1) (i=1,2,…,n/2)时称之为堆

image.png

堆排序

  1. import random
  2. import time
  3. class MaxHeap(object):
  4. def __init__(self):
  5. self._data = []
  6. self._count = len(self._data)
  7. def size(self):
  8. return self._count
  9. def isEmpty(self):
  10. return self._count == 0
  11. def add(self, item):
  12. # 插入元素入堆
  13. self._data.append(item)
  14. self._count += 1
  15. self._shiftup(self._count-1) #堆的序号从0开始
  16. def pop(self):
  17. # 出堆
  18. if self._count > 0:
  19. ret = self._data[0]
  20. self._data[0] = self._data[self._count-1] #移除堆的最顶的元素
  21. self._count -= 1
  22. self._shiftDown(0) #对移除之后的堆进行排序,使之成为最大堆
  23. return ret
  24. def _shiftup(self, index):
  25. # 上移self._data[index],以使它不大于父节点
  26. parent = (index-1)>>1
  27. while index > 0 and self._data[parent] < self._data[index]:
  28. # swap
  29. self._data[parent], self._data[index] = self._data[index], self._data[parent]
  30. index = parent
  31. parent = (index-1)>>1
  32. def _shiftDown(self, index):
  33. # 上移self._data[index],以使它不小于子节点
  34. j = (index << 1) + 1
  35. while j < self._count :
  36. # 有子节点
  37. if j+1 < self._count and self._data[j+1] > self._data[j]:
  38. # 有右子节点,并且右子节点较大
  39. j += 1
  40. if self._data[index] >= self._data[j]:
  41. # 堆的索引位置已经大于两个子节点,不需要交换了
  42. break
  43. self._data[index], self._data[j] = self._data[j], self._data[index]
  44. index = j
  45. j = (index << 1) + 1
  46. def MaxHeap1(self,alist,n): #n表示alist的长度
  47. self._data=n*[0]
  48. for i in range(0,n):
  49. self._data[i]=alist[i]
  50. self._count=n
  51. i=(self._count-1)>>2
  52. while i>=0:
  53. self._shiftDown(i)
  54. i-=1
  55. #通过将数组的数一个一个添加到堆中然后在移出堆的操作实现逆序
  56. def Heapsort1(alist):
  57. maxheap=MaxHeap()
  58. for i in range(0,len(alist)):
  59. maxheap.add(alist[i])
  60. i=maxheap._count-1
  61. while i>=0:
  62. alist[i]=maxheap.pop()
  63. i-=1
  64. #通过开辟一个与数组同长度的堆,然后赋值->shitfdown使得成为最大堆,最后移出堆操作实现逆序
  65. def Heapsort2(alist):
  66. #开辟新空间maxheap
  67. maxheap=MaxHeap()
  68. maxheap.MaxHeap1(alist,len(alist))
  69. i=len(alist)-1
  70. while i>=0:
  71. alist[i]=maxheap.pop()
  72. i-=1
  73. #直接对alist逆排序,不创建堆空间
  74. def Heapsort3(alist):
  75. #对数组heapify
  76. i=(len(alist)-1)>>1
  77. while i>=0:
  78. shiftdown(alist,len(alist),i)
  79. i-=1
  80. #对数组进行逆序
  81. k=len(alist)-1
  82. while k>0:
  83. #交换
  84. alist[k],alist[0]=alist[0],alist[k]
  85. shiftdown(alist,k,0)
  86. k-=1
  87. def shiftdown(alist,n,k):
  88. while 2*k+1<n: #当左孩子没有越界
  89. j=2*k+1
  90. if j+1<n and alist[j+1]>alist[j]:
  91. j+=1
  92. if alist[k]>=alist[j]:
  93. break
  94. alist[k],alist[j]=alist[j],alist[k]
  95. k=j
  96. if __name__ == '__main__':
  97. alist=random.sample(range(0,10000),10000)
  98. start=time.clock()
  99. Heapsort3(alist)
  100. end=time.clock()
  101. print(end-start)