数据结构之优先队列:最小索引优先队列,Python代码实现——15
最小索引优先队列(Min index priority queue)
在之前实现的最大优先队列和最小优先队列,他们可以分别快速访问到队列中最大元索和最小元素,但是他们有一 个缺点,就是没有办法通过索引访问已存在于优先队列中的对象,并更新它们。
为了实现这个目的,在优先队列的基础上,学习一种新的数据结构,索引优先队列。
接下来我们以最小索引优先队列举列,最大优先索引队列,有兴趣可以自行实现。
实现思路
实现功能的三个重要数组
- 数组items,储存无序插入的元素的数组
- 数组pq,假设将items储存的元素进行从小到大排序,并且items对应的原索引依旧保持不变,而pq储存的元素就是items排序过后元素的原索引(参照下图可更好地理解)
- 数组qp,qp的元素对应pq中的索引, qp的索引对应pq中的元素(也就对应着未排序的items中的元素,与items元素的索引保持一致)
这样删除时只需要根据传入的索引在qp中寻找对应的元素就可以跟快地找到了
实现的操作方法
- size()获取队列的大小
- is_empty()判断队列是否为空
- less(x, y)对传入的两个索引对应当前队列的元素进行大小比较
- swap(i, j)对传入的两个索引对应当前队列中的元素进行值交换
- min_elem_index()获取最小元素的索引
- is_index_exist()判断索引在当前队列中是否对应一个元素
- insert(index, item)指定索引index处插入一个元素item
- delete_min_elem()删除最小元素,并返回最小元素插入队列时的索引
- change_item(idx, itm)指定索引idx处,将该处元素替换为itm
- swim()上浮排序操作,同之前堆的排序中介绍
- 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相关推荐
- 02优先队列和索引优先队列-优先队列-数据结构和算法(Java)
文章目录 1 概述 1.1 需求 1.2 优先队列特点 1.3 优先队列分类 1.4 应用场景 1.5 相关延伸 2 说明 3 索引优先队列 3.1 实现思路 3.2 API设计 3.2 代码实现及简 ...
- 特征缩放+无量纲化:最小最大缩放 - Python代码实现
特征缩放+无量纲化:最小最大缩放 - Python代码实现 在机器学习的特征工程中,对于数据进行特征缩放和无量纲化是非常重要的步骤.其中,最小最大缩放(MinMaxScaler)是一种经典的无量纲化方 ...
- 索引超出了数组界限_还在用优先队列?来试试索引优先队列吧(优先队列amp;索引优先队列)...
一.优先队列 简介 优先队列也被称为堆(heap),队列中允许的操作是 先进先出(FIFO),在队尾插入元素,在队头取出元素.而堆也是一样,在堆底插入元素,在堆顶取出元素.二叉树的衍生,有最小堆最大堆 ...
- ElasticSearch通过Scroll方式遍历索引(Python代码)
当我们要查询的数据量过大的时候,用es的from+size的方式会报错,会提示你from+size不能大于10000 那么可以用es的scroll方式,实际是一种深度分页机制 直接上代码: #-*- ...
- 599. 两个列表的最小索引总和【C++】
题目地址: 599. 两个列表的最小索引总和 解题代码: class Solution { public:vector<string> findRestaurant(vector<s ...
- 数据结构之优先队列:优先队列的介绍与基础操作实现,Python代码实现——14
优先队列(Priority queue)的介绍 优先队列是计算机中一种抽象的数据结构类,它有着一个类似和队列或者堆的结构,但是其中每个元素额外有一个优先级别 在一个优先队列中,一个高优先顺序的元素会先 ...
- python structure_GitHub - CYZYZG/Data_Structure_with_Python: 这是我在学习《基于Python的数据结构》的时候的笔记与代码...
Data_Structure_with_Python 这是我在学习<基于Python的数据结构>的时候的笔记与代码 主要参考:数据结构与算法(Python) 对于算法的时间效率,我们可以用 ...
- 数据结构之图:图的搜索,Python代码实现——23
图的搜索 深度优先搜索(Depth First Search) 定义 从例子出发理解 DFS是一种用于遍历或搜寻树类或图类数据结构的算法,这种算法从根结点出发(如果是图,则任意选择一个顶点作为根结点) ...
- 数据结构之并查集:并查集的介绍与Python代码实现——18
并查集的介绍 并查集(Union-find)数据结构也称作合并查找集(Merge-find set)或者不相交集数据结构(disjoint-set data structure),它是一种记录了由一个 ...
最新文章
- 简单几步写一个laravel扩展包
- Verilog与SystemVerilog编程陷阱:怎样避免101个常犯的编码错误
- EasyUI中Window窗口的简单使用
- 学校测试-2015-2-27
- 电脑不能打字_电脑拼音打字快速入门秘籍
- cg word List 3
- 蚂蚁集团沈凋墨:Kubernetes-微内核的分布式操作系统
- c语言abc变def,C语言的permutation求解
- linux使用mount命令挂载、umount命令取消挂载
- shell学习之跳出循环
- HTML语言的三要素,web前端基础技术三要素HTML、CSS、JavaScript
- 批量将点shp转成线shp
- Spket,eclipse下安装Spket插件,格式化js
- JS 替换字符串中指定字符
- 使用电脑风扇控制软件Macs Fan Control Pro更好的管理电风扇
- web网站中常见攻击手法与原理
- 产品经理的年终总结可以这样写
- OLS最小二乘法回归模型
- html涟漪效果,涟漪效果.html
- 余承东:华为技术走在产业前列,别人想超越很难;理想销量夺冠后,员工不满年终奖打折;黑客窃取GitHub代码签名证书|极客头条
热门文章
- va_list/va_start/va_end的使用
- 爬虫——————爬取中金所,深交所,上交所期权数据
- python剑指offer替换空格_迷人的算法-剑指offer面试题5:替换空格
- 如何使用notepad运行python程序
- 机器学习之LDA主题模型算法
- 给未来的自己一封信计算机,给未来的自己的一封信范文(精选5篇)
- ocsng mysql connection problem_OCSNG 介绍及其工作原理
- 《c语言深度剖析》读书笔记
- [JSOI2007]建筑抢修 (贪心)
- H5活动产品设计指南基础版