zoukankan      html  css  js  c++  java
  • 数据结构与算法(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)
  • 相关阅读:
    树上启发式合并_训练总结+题目清单
    Wannafly Day2 E 阔力梯的树(树上启发式合并)
    profile(/etc/profile)和bash_profile的区别
    MacOS配置.bash_profile,重启终端后配置失效和MacOS .zshrc does not exist问题
    Markdown入门学习202004
    把-图片的链接-下载到本地(服务器);
    前端Vue- v-for 循环中删除 元素;
    关于谷歌浏览器(Chrome)前端JS方法调用方法,运行顺序出错问题;
    国外的api之ASANA-java开发-ASANAAPI(真难!)
    vue脚手架3.x完整版
  • 原文地址:https://www.cnblogs.com/yeshengCqupt/p/13381155.html
Copyright © 2011-2022 走看看