《数据结构与算法Python语言描述》学习笔记chap6(3)优先队列
20191201
优先队列
作为缓存结构,优先队列与栈和队列类似,可以将数据元素保存其中,可以访问和弹出。
优先队列的特点是存入其中的每项数据都另外附有一个数值,表示这个项的优先程度,称为其优先级。优先队列应该保证,在任何时候访问或弹出的,总是当时在这个结构里保存的所有元素中优先级最高的。如果该元素不弹出,再次访问还将得到他。
优先队列的线性表实现
基于线性表的实现
两种可能的实现方案:
1)在存入数据时,保证表中元素始终按优先顺序排列;任何时候都可以直接取到当时在表里最优先元素。
采用有组织的元素存放方式,存入元素的操作比较麻烦,效率可能较低,但访问和弹出比较方便;
2)存入数据时采用最简单的方式,需要用时,通过检索找到最优先的元素。
基于list实现优先队列
# 优先队列:较小的优先级更高,倒序排列,队头是最小的元素
class PrioQueueError(ValueError):
pass
class PrioQue:
def __init__(self,elist=[]):
self._elems = list(elist)
self._elems.sort(reverse=True) # 将参数从大到小排列
def enqueue(self,e):
"""插入到正确的位置"""
i = len(self._elems) - 1
while i >= 0:
if self._elems[i] <= e:
i -= 1
else:
break
self._elems.insert(i+1,e)
def is_empty(self):
return not self._elems
def peek(self):
if self.is_empty():
raise PrioQueueError("in top")
return self._elems[-1]
def dequeue(self):
if self.is_empty():
raise PrioQueueError("in pop")
return self._elems.pop()
prique = PrioQue([3,7,4,8,1])
for i in range(0,3):
prique.enqueue(i)
while not prique.is_empty():
print(prique.dequeue())
运行结果:
0
1
1
2
3
4
7
8
《数据结构与算法Python语言描述》学习笔记chap6(4)堆排序
20191206
优先队列的堆实现
堆及其性质
堆:完全二叉树,但数据要满足一种特殊的堆序,
小顶堆:队中最优先的元素位于二叉树的根节点;
大顶堆:每个结点的数据都大于或等于其子结点的数据,堆顶是最大元素。
堆排序
def heap_sort(elems):
def siftdown(elems,e,begin,end):
"""将数据插入到合适的位置,作为主函数的内部函数"""
i,j = begin,begin*2+1
while j < end :
if j +1 < end and elems[j+1] < elems[j]:
j += 1
if e < elems[j]:
break
elems[i] = elems[j]
i , j = j,2*j+1
elems[i] = e
end = len(elems)
# 构建小根堆
for i in range(end//2,-1,-1):
siftdown(elems,elems[i],i,end)
# 依次取出最小的元素
print('依次取出最小的元素')
for i in range((end-1),0,-1):
e = elems[i]
elems[i] = elems[0]
siftdown(elems,e,0,i) #调整结构
print(elems[0])
# end = 9
# for i in range(end//2,-1,-1):
# print(i,end = '')
#
# print('')
# for i in range((end - 1), 0, -1):
# print(i,end = '')
elems = [1,6,8,0,3,5,2]
heap_sort(elems)
注:
range(0,9,-1)
左闭右开,-1表示倒序,所以包含的范围是:0-8
输出应为:8,7,6,5,4,3,2,1,0