优先队列/oriority queue 之最大优先队列的实现
优先队列(priority queue)
是一种用来维护一组数据集合S的数据结构。
每一个元素都有一个相关的值,被称为关键字key。
这里以实现最大优先队列为例子
最大优先队列支持的操作如下:
INSERT(S,x):把元素x插入集合S中
MAXIMUN(S):返回S中具有最大键字的元素。
EXTRACT-MAX(S):去掉并且返回S中具有最大键字的元素。
INCREASE-KEY(S,x,k):将元素x的关键字增加到k(k>=x)
下面对于最大优先队列的具体实现进行描述。
首先,最大优先队列是基于堆的,所以其相关的建立堆、维护堆操作在这里不赘述。详见上一篇随笔。
heap_maximun(arr,heap_size):在O(1)的时间内实现MAXIMUN(S)的操作。
1 int heapmax(int arr[]) 2 { 3 return arr[1];//返回堆顶 4 }
heap_extract_max(arr,heap_size):实现EXTRACT-MAX(S)的操作。吐出堆顶元素,并且把堆顶位置元素与最后一个位置的元素交换,heap_size减1,而后调用维护堆(max_heapify)函数对堆进行调整。使其在吐出一个元素之后仍然满足大根堆的性质。
1 int heap_extract_max(int arr[],int &heap_size)//去掉并返回arr中具有最大键字的元素 2 { 3 if(heap_size<1) // 4 { 5 cout<<"heap underflow"<<endl; 6 return -1; 7 } 8 int max_=arr[1]; 9 arr[1]=arr[heap_size]; 10 heap_size--; 11 max_heapify(arr,1,heap_size); 12 return max_; 13 }
heap_increase_key(arr,x,k,heap_size):实现INCREASE-KEY(S,x,k)的操作。把元素x的关键字值增加到key,假设k的值不小于x原本关键字的值。在优先队列中,其元素由下标x来标识;而增大arr[i]的关键字有可能会违反最大堆的性质。所以在这个算法中,使用了【插入循环】的方式,从当前结点到根结点的路径上寻找新增关键字恰当的插入位置。
该过程会使结点x与其父结点的值比较。如果当前元素的关键字比较大,则交换当前元素与父结点元素的值。直到当前元素的关键字的值小于父元素关键字的值为止,此时已重新符合大根堆的性质。
如下图,显示了heap_increase_key的操作过程。(图截自算法导论)
int heap_increase_key(int arr[],int x,int k,int heap_size)//把元素x的关键字值增加到key,假设k的值不小于x原本关键字的值 {if(k<arr[x]){cout<<"new key is smaller than current key";}arr[x]=k;while(x>1&&arr[x/2]<arr[x])//插入值x的粑粑比崽值小,于是交换元素值 {swap(arr[x/2],arr[x]);x=x/2;} }
max_heap_insert:在原来队列的基础上新增一个元素。这个算法通过先增加一个值为负无穷的关键字作为叶结点来扩展最大堆,而后调用heap_increase_key来为新的结点设置对应的关键字,保持大根堆的性质。
1 void max_heap_insert(int arr[],int k,int &heap_size)//把元素x值插入到集合中 2 { 3 heap_size++; 4 arr[heap_size]=-1;//通过增加一个关键字为负无穷的叶节点来扩展最大堆,这里用-1代替 5 heap_increase_key(arr,heap_size,k,heap_size); 6 }
总实现代码如下:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdlib> 4 using namespace std; 5 void max_heapify(int arr[],int i,int heap_size)//维护堆 6 { 7 int largest; 8 int left=2*i; 9 int right=2*i+1; 10 if(left<=heap_size&&arr[left]>arr[i]) largest=left; 11 else largest=i; 12 if(right<=heap_size&&arr[right]>arr[largest]) 13 largest=right; 14 if(largest!=i) 15 { 16 swap(arr[largest],arr[i]); 17 max_heapify(arr,largest,heap_size); 18 } 19 } 20 void build_max_heap(int arr[],int length)//建立堆 21 { 22 int heap_size=length; 23 for(int i=length/2; i>=1; i--) 24 { 25 max_heapify(arr,i,heap_size); 26 } 27 } 28 void heapsort(int arr[],int length) 29 { 30 int heap_size=length; 31 build_max_heap(arr,length); 32 for(int i=length; i>=2; i--) 33 { 34 swap(arr[1],arr[i]); 35 heap_size--; 36 max_heapify(arr,1,heap_size); 37 } 38 } 39 int heapmax(int arr[]) 40 { 41 return arr[1];//返回堆顶 42 } 43 int heap_extract_max(int arr[],int &heap_size)//去掉并返回arr中具有最大键字的元素 44 { 45 if(heap_size<1) // 46 { 47 cout<<"heap underflow"<<endl; 48 return -1; 49 } 50 int max_=arr[1]; 51 arr[1]=arr[heap_size]; 52 heap_size--; 53 max_heapify(arr,1,heap_size); 54 return max_; 55 } 56 int heap_increase_key(int arr[],int x,int k,int heap_size)//把元素x的关键字值增加到key,假设k的值不小于x原本关键字的值 57 { 58 if(k<arr[x]) 59 { 60 cout<<"new key is smaller than current key"; 61 } 62 arr[x]=k; 63 while(x>1&&arr[x/2]<arr[x])//插入值x的粑粑比崽值小,于是交换元素值 64 { 65 swap(arr[x/2],arr[x]); 66 x=x/2; 67 } 68 } 69 void max_heap_insert(int arr[],int k,int &heap_size)//把元素x值插入到集合中 70 { 71 heap_size++; 72 arr[heap_size]=-1;//通过增加一个关键字为负无穷的叶节点来扩展最大堆,这里用-1代替 73 heap_increase_key(arr,heap_size,k,heap_size); 74 } 75 void show(int arr[],int heap_size) 76 { 77 cout<<"show the heap:"; 78 for(int i=1; i<=heap_size; i++) 79 { 80 cout<<arr[i]<<" "; 81 } 82 cout<<endl; 83 } 84 int main() 85 { 86 int arr[]= {0,5,6,8,99,102,3,54,76,89,21}; 87 int heap_size=10; 88 build_max_heap(arr,heap_size);//建堆 89 int maxn=heapmax(arr); 90 cout<<"the max data is:"<<maxn<<endl; 91 maxn=heap_extract_max(arr,heap_size); 92 cout<<"now the max data "<<maxn<<" was deleted."<<endl; 93 show(arr,heap_size); 94 heapsort(arr,heap_size); 95 cout<<"after sort and"; 96 show(arr,heap_size); 97 int i=6,key=80; 98 heap_increase_key(arr,i,key,heap_size);//把堆中第i个元素的值改为key值。 99 max_heap_insert(arr,100,heap_size);//插入新值100 100 show(arr,heap_size); 101 heapsort(arr,heap_size); 102 cout<<"after sort and"; 103 show(arr,heap_size); 104 return 0; 105 }
测试截图:
转载于:https://www.cnblogs.com/AKsnoopy/p/8556319.html
优先队列/oriority queue 之最大优先队列的实现相关推荐
- C语言优先队列作用,C语言实现优先队列(priority queue)
堆排序是一个比较优秀的算法,堆这种数据结构在现实生活中有很多的应用,比如堆可以作为一个优先队列来使用,作为一个高效的优先队列,它与堆的结构一样,都有最大优先队列,最小优先队列.优先队列priority ...
- 优先队列(priority queue)
目录 一,优先队列 二,STL优先队列 三,二叉堆实现优先队列 四,二项堆实现优先队列 五,线段树实现优先队列 六,OJ实战 力扣 295. 数据流的中位数 一,优先队列 优先队列可以插入元素.查询最 ...
- c++ STL:队列queue、优先队列priority queue 的使用
说明:本文全文转载而来,原文链接:http://www.cppblog.com/wanghaiguang/archive/2012/06/05/177644.html C++ Queues(队列) C ...
- Java优先队列 Priority Queue
2019独角兽企业重金招聘Python工程师标准>>> 优先队列是一种用来维护一组元素构成的结合S的数据结构,其中每个元素都有一个关键字key,元素之间的比较都是通过key来比较的. ...
- heaps 和 priority queue堆和优先队列的定义和数据结构表示
heaps 堆:并非一对杂乱无章的结构, 堆是一种存在特殊关系的树. 是一种半排序的树, 所有的父节点大于子节点(max heaps) 或 所有的父节点小于子节点(min heaps).上图为max ...
- python 优先队列_Python Queue队列实现线程通信
queue 模块下提供了几个阻塞队列,这些队列主要用于实现线程通信.在 queue 模块下主要提供了三个类,分别代表三种队列,它们的主要区别就在于进队列.出队列的不同.关于这三个队列类的简单介绍如下: ...
- python 优先队列_Python中heapq与优先队列【详细】
本文始发于个人公众号:TechFlow, 原创不易,求个关注 今天的文章来介绍Python当中一个蛮有用的库--heapq. heapq的全写是heap queue,是堆队列的意思.这里的堆和队列都是 ...
- 索引超出了数组界限_还在用优先队列?来试试索引优先队列吧(优先队列amp;索引优先队列)...
一.优先队列 简介 优先队列也被称为堆(heap),队列中允许的操作是 先进先出(FIFO),在队尾插入元素,在队头取出元素.而堆也是一样,在堆底插入元素,在堆顶取出元素.二叉树的衍生,有最小堆最大堆 ...
- c语言优先队列对数组的排序,优先队列+sort+栈+队列讲解
队列我们都知道,是一种先进后出的数据结构. 队列的基本操作http://blog.csdn.net/qq_32680617/article/details/50822430 而优先队列是把队列内部的数 ...
- 数据结构之优先队列:优先队列的介绍与基础操作实现,Python代码实现——14
优先队列(Priority queue)的介绍 优先队列是计算机中一种抽象的数据结构类,它有着一个类似和队列或者堆的结构,但是其中每个元素额外有一个优先级别 在一个优先队列中,一个高优先顺序的元素会先 ...
最新文章
- oracle官网能用的账号,oracle 官方登录账号Oracle的在windows下的安装及使用
- 第三部分:Android 应用程序接口指南---第三节:应用程序资源---第四章 本地化...
- php7.2与php5.6共存,同域名下php5.6与7.2同时运行
- 内核中_init,_exit中的作用
- 将list中的元素按照属性分类成树状的map
- java getCause()与e.getMessage() 异常日志区别
- activity绑定service
- 64 位SQL Server 2005通过DB link链接32位SQL Server 2000 的bug解决
- Java开发笔记(一百三十三)Swing的菜单
- STC12C5A60S2在LCD1602基本显示程序
- y53拆机视频教程_戴尔笔记本P35G拆机全过程图解
- linux怎么复制文件和移动文件
- cairo显示多行文本
- 磨金石教育摄影技能干货分享|王汉冰摄影作品欣赏—《沙狐之眼》
- Ubuntu下U盘只读文件系统,图标上锁,文件无法写入
- iPad 2第一次开机与激活指南
- 《数据库原理》实验六 SQL数据查询实验
- 正则表达式贪婪模式、懒惰模式与独占模式浅析
- 智能锁忘记密码怎么办
- Linux编写脚本 Hello word
热门文章
- 【渝粤教育】国家开放大学2018年秋季 1141t工程经济与管理 参考试题
- 【渝粤教育】国家开放大学2018年春季 0221-22T数字电子电路 参考试题
- VC中ComboBox控件用法详解
- Linux系统是否被植入木马的排查流程梳理
- Here we are 团队简介
- C和指针---读书笔记9
- [转]asp实现数据库导出excel文件
- mybatis配置文件祥解(mybatis.xml)
- JS--我发现,原来你是这样的JS:面向对象编程OOP[3]--(JS继承)
- windows下使用wineshark分析抓取本地回环包