最小索引优先队列(Min index priority queue)

在之前实现的最大优先队列和最小优先队列,他们可以分别快速访问到队列中最大元索和最小元素,但是他们有一 个缺点,就是没有办法通过索引访问已存在于优先队列中的对象,并更新它们。

为了实现这个目的,在优先队列的基础上,学习一种新的数据结构,索引优先队列。

接下来我们以最小索引优先队列举列,最大优先索引队列,有兴趣可以自行实现。

实现思路

实现功能的三个重要数组

  1. 数组items,储存无序插入的元素的数组
  2. 数组pq,假设将items储存的元素进行从小到大排序,并且items对应的原索引依旧保持不变,而pq储存的元素就是items排序过后元素的原索引(参照下图可更好地理解)
  3. 数组qp,qp的元素对应pq中的索引, qp的索引对应pq中的元素(也就对应着未排序的items中的元素,与items元素的索引保持一致)
    这样删除时只需要根据传入的索引在qp中寻找对应的元素就可以跟快地找到了

实现的操作方法

  1. size()获取队列的大小
  2. is_empty()判断队列是否为空
  3. less(x, y)对传入的两个索引对应当前队列的元素进行大小比较
  4. swap(i, j)对传入的两个索引对应当前队列中的元素进行值交换
  5. min_elem_index()获取最小元素的索引
  6. is_index_exist()判断索引在当前队列中是否对应一个元素
  7. insert(index, item)指定索引index处插入一个元素item
  8. delete_min_elem()删除最小元素,并返回最小元素插入队列时的索引
  9. change_item(idx, itm)指定索引idx处,将该处元素替换为itm
  10. swim()上浮排序操作,同之前堆的排序中介绍
  11. sink()下沉排序操作,同之前堆的排序中介绍

Python代码实现

import operatorclass IndexMinPriorityQueue:def __init__(self, length):self.items = [None for _ in range(length)]# Ascendingly sort items and memorize the item's relative index in itemsself.pq = [None] + [i if self.items[i] else None for i in range(len(self.items))]# Its index is associate with elements in pq, and also syncs with indices of list itemsself.qp = [i if self.pq[i] else None for i in range(len(self.pq))]self.N = 0def size(self):return self.Ndef is_empty(self):return self.N == 0def less(self, i, j):"""Compare the given two items in self.items"""return operator.lt(self.items[self.pq[i]], self.items[self.pq[j]])def swap(self, i, j):"""But change the position of the two items in the subsidiary pq and qp lists"""self.pq[i], self.pq[j] = self.pq[j], self.pq[i]self.qp[self.pq[i]], self.qp[self.pq[j]] = i, jdef min_elem_index(self):"""Find the minimum element's index"""return self.pq[1]def is_index_exist(self, index):"""Judge if the given index is exist in this queue"""return self.qp[index] is not Nonedef insert(self, index, item):"""Insert an element associated with the element's index in this queue"""if self.is_index_exist(index):returnself.items[index] = itemself.N += 1# Now it isn't a orderly queueself.pq[self.N] = indexself.qp[index] = self.N# swim the last element to make list pq orderedself.swim(self.N)def delete_min_elem(self):"""Delete the minimum element, and return its index"""min_index = self.pq[1]# print(f"min_ele: {self.items[min_index]}")self.swap(1, self.N)self.pq[self.N] = Noneself.qp[min_index] = Noneself.items[min_index] = Noneself.N -= 1self.sink(1)return min_indexdef change_item(self, idx, itm):"""Substitute a item which index=idx with a new item which value=itm"""self.items[idx] = itmk = self.qp[idx]self.sink(k)self.swim(k)def swim(self, index):"""Move the smaller element up; We should only change order in pq and qp"""while index > 1:# Compare the current node with its parent node, if smaller, swim upif self.less(index, int(index/2)):  # Compare values in itemsself.swap(index, int(index/2))  # But swap the mapping position in pq and qpindex = int(index/2)def sink(self, index):"""Move the bigger element down; We should only change order in pq and qp"""# print(f"SINK: idx:{index} N:{self.N}")while 2*index <= self.N:index_smaller = 2*index if 2*index+1 > self.N else \(2*index if self.less(2*index, 2*index+1) else 2*index+1)# print(f"index_smaller: {index_smaller}")# print(f"index: {index}")if self.less(index, index_smaller):breakself.swap(index, index_smaller)index = index_smaller

测试代码

if __name__ == '__main__':IMPQ = IndexMinPriorityQueue(10)IMPQ.insert(0, 'C')IMPQ.insert(1, 'E')IMPQ.insert(2, 'A')print(f"After three insert list items now is: {IMPQ.items}")# print(f"pq: {IMPQ.pq}")# print(f"qp: {IMPQ.qp}")# print(f"min_elem_index: {IMPQ.min_elem_index()}")index, item = 0, 'B'IMPQ.change_item(0, 'B')print(f"Changed the item in index[{index}] to {item}, items now is {IMPQ.items}")index, item = 0, 'V'IMPQ.change_item(0, 'V')print(f"Changed the item in index[{index}] to {item}, items now is {IMPQ.items}")while not IMPQ.is_empty():res = IMPQ.delete_min_elem()print(f"Pop the minimum element: {res}")print(f"After delete all elements , its size: {IMPQ.size()}")print(IMPQ.is_index_exist(0))

测试结果

After three insert list items now is: ['C', 'E', 'A', None, None, None, None, None, None, None]
Changed the item in index[0] to B, items now is ['B', 'E', 'A', None, None, None, None, None, None, None]
Changed the item in index[0] to V, items now is ['V', 'E', 'A', None, None, None, None, None, None, None]
Pop the minimum element: 2
Pop the minimum element: 1
Pop the minimum element: 0
After delete all elements , its size: 0
False

这里为了测试结果直观,直接将数组items拿出来了,注意items中的元素是不会改变位置的,实际改变的是用来定位items中元素的pq和qp数组

数据结构之优先队列:最小索引优先队列,Python代码实现——15相关推荐

  1. 02优先队列和索引优先队列-优先队列-数据结构和算法(Java)

    文章目录 1 概述 1.1 需求 1.2 优先队列特点 1.3 优先队列分类 1.4 应用场景 1.5 相关延伸 2 说明 3 索引优先队列 3.1 实现思路 3.2 API设计 3.2 代码实现及简 ...

  2. 特征缩放+无量纲化:最小最大缩放 - Python代码实现

    特征缩放+无量纲化:最小最大缩放 - Python代码实现 在机器学习的特征工程中,对于数据进行特征缩放和无量纲化是非常重要的步骤.其中,最小最大缩放(MinMaxScaler)是一种经典的无量纲化方 ...

  3. 索引超出了数组界限_还在用优先队列?来试试索引优先队列吧(优先队列amp;索引优先队列)...

    一.优先队列 简介 优先队列也被称为堆(heap),队列中允许的操作是 先进先出(FIFO),在队尾插入元素,在队头取出元素.而堆也是一样,在堆底插入元素,在堆顶取出元素.二叉树的衍生,有最小堆最大堆 ...

  4. ElasticSearch通过Scroll方式遍历索引(Python代码)

    当我们要查询的数据量过大的时候,用es的from+size的方式会报错,会提示你from+size不能大于10000 那么可以用es的scroll方式,实际是一种深度分页机制 直接上代码: #-*- ...

  5. 599. 两个列表的最小索引总和【C++】

    题目地址: 599. 两个列表的最小索引总和 解题代码: class Solution { public:vector<string> findRestaurant(vector<s ...

  6. 数据结构之优先队列:优先队列的介绍与基础操作实现,Python代码实现——14

    优先队列(Priority queue)的介绍 优先队列是计算机中一种抽象的数据结构类,它有着一个类似和队列或者堆的结构,但是其中每个元素额外有一个优先级别 在一个优先队列中,一个高优先顺序的元素会先 ...

  7. python structure_GitHub - CYZYZG/Data_Structure_with_Python: 这是我在学习《基于Python的数据结构》的时候的笔记与代码...

    Data_Structure_with_Python 这是我在学习<基于Python的数据结构>的时候的笔记与代码 主要参考:数据结构与算法(Python) 对于算法的时间效率,我们可以用 ...

  8. 数据结构之图:图的搜索,Python代码实现——23

    图的搜索 深度优先搜索(Depth First Search) 定义 从例子出发理解 DFS是一种用于遍历或搜寻树类或图类数据结构的算法,这种算法从根结点出发(如果是图,则任意选择一个顶点作为根结点) ...

  9. 数据结构之并查集:并查集的介绍与Python代码实现——18

    并查集的介绍 并查集(Union-find)数据结构也称作合并查找集(Merge-find set)或者不相交集数据结构(disjoint-set data structure),它是一种记录了由一个 ...

最新文章

  1. 简单几步写一个laravel扩展包
  2. Verilog与SystemVerilog编程陷阱:怎样避免101个常犯的编码错误
  3. EasyUI中Window窗口的简单使用
  4. 学校测试-2015-2-27
  5. 电脑不能打字_电脑拼音打字快速入门秘籍
  6. cg word List 3
  7. 蚂蚁集团沈凋墨:Kubernetes-微内核的分布式操作系统
  8. c语言abc变def,C语言的permutation求解
  9. linux使用mount命令挂载、umount命令取消挂载
  10. shell学习之跳出循环
  11. HTML语言的三要素,web前端基础技术三要素HTML、CSS、JavaScript
  12. 批量将点shp转成线shp
  13. Spket,eclipse下安装Spket插件,格式化js
  14. JS 替换字符串中指定字符
  15. 使用电脑风扇控制软件Macs Fan Control Pro更好的管理电风扇
  16. web网站中常见攻击手法与原理
  17. 产品经理的年终总结可以这样写
  18. OLS最小二乘法回归模型
  19. html涟漪效果,涟漪效果.html
  20. 余承东:华为技术走在产业前列,别人想超越很难;理想销量夺冠后,员工不满年终奖打折;黑客窃取GitHub代码签名证书|极客头条

热门文章

  1. va_list/va_start/va_end的使用
  2. 爬虫——————爬取中金所,深交所,上交所期权数据
  3. python剑指offer替换空格_迷人的算法-剑指offer面试题5:替换空格
  4. 如何使用notepad运行python程序
  5. 机器学习之LDA主题模型算法
  6. 给未来的自己一封信计算机,给未来的自己的一封信范文(精选5篇)
  7. ocsng mysql connection problem_OCSNG 介绍及其工作原理
  8. 《c语言深度剖析》读书笔记
  9. [JSOI2007]建筑抢修 (贪心)
  10. H5活动产品设计指南基础版