数据结构与算法(24)——优先队列和二叉堆

  • 优先队列Priority Queue

性质:队首出队。高优先级的数据项在队首,而低优先级的数据项则排在后面。

实现优先队列额经典方案是二叉堆数据结构。二叉堆能够优先将队列的入队和出队复杂度都保持在O(log n)

  • 二叉堆Binary Heap实现优先队列

BinaryHeap():创建一个空二叉堆对象;

insert(k):将新key加入到堆中;

findMin():返回堆中的最小项,最小项仍保留在堆中;

delMin():返回堆中的最小项,同时从堆中删 除;

isEmpty():返回堆是否为空;

size():返回堆中key的个数;

buildHeap(list):从一个key列表创建新堆

用非嵌套列表实现二叉堆。

平衡二叉树:树根左右子树拥有相同数量的节点。

 

 

完全二叉树:叶节点最多只出现在最底层和次底层,而且最底层的叶节点都连续集中在最左边, 每个内部节点都有两个子节点,最多可有1个节点例外。

 

 完全二叉树的列表实现及性质:如果节点的下标为p,那么其左子节点下标为2p, 右子节点为2p+1,其父节点下标为p//2 

 

 

 

  •  堆次序Heap Order

任何一个节点x,其父节点p中的key均小 于x中的key 

  •  二叉堆的实现

inserKey:当添加一个新key时,新key加在列表末尾,显然无法保持“堆”次序 虽然对其它路径的次序没有影响,但对于其到根的路径可能破坏次序。因此需要将完全二叉树最左边的叶子节点“上浮”到其正确的位置。

 

 

delMin():移走整个堆中最小的key:根节点heapList[1] 为了保持“完全二叉树”的性质,只用最后一个 节点来代替根节点 。这么简单的替换,还是破坏了“堆”次序 ,将新的根节点沿着一条路径“下沉”, 直到比两个子节点都小,直到比两个子节点都小。

 

 

 

 

class BinHeap:
    def __init__(self): #初始化
self.heapList
= [0] self.currentSize = 0 def insert(self, k): self.heapList.append(k) #新key添加到末尾 self.currentSize = self.currentSize + 1 self.percUp(self.currentSize) #新key上浮 def percUp(self, i): #沿路径向上 while i // 2 >0: #沿着路径往上遍历其父节点 if self.heapList[i] < self.heapList[i // 2]: tmp = self.heapList[i // 2] self.heapList[i //2] = self.heapList[i] self.heapList[i] = tmp i = i // 2 def percDown(self, i): #交换下沉 while(i * 2) <= self.currentSize: mc = self.minChild(i) if self.heapList[i] > self.heapList[mc]: tmp = self.heapList[i] self.heapList[i] = self.heapList[mc] self.heapList[mc] = tmp i = mc def minChild(self, i): if i * 2 + 1 > self. currentSize: #唯一一个子节点 return i * 2 else: #返回较小的 if self.heapList[i * 2] < self.heapList[ i * 2 + 1]: return i * 2 +1 def delMin(self): retval = self.heapList[1] #移走堆顶 self.heapList[1] = self.heapList[self.currentSize] #把最后一个搬到根节点上来 self.currentSize = self.currentSize - 1 #pop掉原来的根节点 self.heapList.pop() self.percDown(1) return retval def buildHeap(self, alist): #下沉 i = len(alist) // 2#从最后节点的父节点开始下沉 self.currentSize = len(alist) self.heapList = [0] + alist[:] print(len(self.heapList), i) while (i > 0): print(self.heapList, i) self.percDown(i) i = i - 1 print(self.heapList, i)

 

posted @ 2020-07-29 19:02  Yelush  阅读(228)  评论(0编辑  收藏  举报