优先队列/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)的操作。
int heapmax(int arr[])
{
return arr[];//返回堆顶
}
heap_extract_max(arr,heap_size):实现EXTRACT-MAX(S)的操作。吐出堆顶元素,并且把堆顶位置元素与最后一个位置的元素交换,heap_size减1,而后调用维护堆(max_heapify)函数对堆进行调整。使其在吐出一个元素之后仍然满足大根堆的性质。
int heap_extract_max(int arr[],int &heap_size)//去掉并返回arr中具有最大键字的元素
{
if(heap_size<) //
{
cout<<"heap underflow"<<endl;
return -;
}
int max_=arr[];
arr[]=arr[heap_size];
heap_size--;
max_heapify(arr,,heap_size);
return max_;
}
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>&&arr[x/]<arr[x])//插入值x的粑粑比崽值小,于是交换元素值
{
swap(arr[x/],arr[x]);
x=x/;
}
}
max_heap_insert:在原来队列的基础上新增一个元素。这个算法通过先增加一个值为负无穷的关键字作为叶结点来扩展最大堆,而后调用heap_increase_key来为新的结点设置对应的关键字,保持大根堆的性质。
void max_heap_insert(int arr[],int k,int &heap_size)//把元素x值插入到集合中
{
heap_size++;
arr[heap_size]=-;//通过增加一个关键字为负无穷的叶节点来扩展最大堆,这里用-1代替
heap_increase_key(arr,heap_size,k,heap_size);
}
总实现代码如下:
#include<iostream>
#include<algorithm>
#include<cstdlib>
using namespace std;
void max_heapify(int arr[],int i,int heap_size)//维护堆
{
int largest;
int left=*i;
int right=*i+;
if(left<=heap_size&&arr[left]>arr[i]) largest=left;
else largest=i;
if(right<=heap_size&&arr[right]>arr[largest])
largest=right;
if(largest!=i)
{
swap(arr[largest],arr[i]);
max_heapify(arr,largest,heap_size);
}
}
void build_max_heap(int arr[],int length)//建立堆
{
int heap_size=length;
for(int i=length/; i>=; i--)
{
max_heapify(arr,i,heap_size);
}
}
void heapsort(int arr[],int length)
{
int heap_size=length;
build_max_heap(arr,length);
for(int i=length; i>=; i--)
{
swap(arr[],arr[i]);
heap_size--;
max_heapify(arr,,heap_size);
}
}
int heapmax(int arr[])
{
return arr[];//返回堆顶
}
int heap_extract_max(int arr[],int &heap_size)//去掉并返回arr中具有最大键字的元素
{
if(heap_size<) //
{
cout<<"heap underflow"<<endl;
return -;
}
int max_=arr[];
arr[]=arr[heap_size];
heap_size--;
max_heapify(arr,,heap_size);
return max_;
}
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>&&arr[x/]<arr[x])//插入值x的粑粑比崽值小,于是交换元素值
{
swap(arr[x/],arr[x]);
x=x/;
}
}
void max_heap_insert(int arr[],int k,int &heap_size)//把元素x值插入到集合中
{
heap_size++;
arr[heap_size]=-;//通过增加一个关键字为负无穷的叶节点来扩展最大堆,这里用-1代替
heap_increase_key(arr,heap_size,k,heap_size);
}
void show(int arr[],int heap_size)
{
cout<<"show the heap:";
for(int i=; i<=heap_size; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main()
{
int arr[]= {,,,,,,,,,,};
int heap_size=;
build_max_heap(arr,heap_size);//建堆
int maxn=heapmax(arr);
cout<<"the max data is:"<<maxn<<endl;
maxn=heap_extract_max(arr,heap_size);
cout<<"now the max data "<<maxn<<" was deleted."<<endl;
show(arr,heap_size);
heapsort(arr,heap_size);
cout<<"after sort and";
show(arr,heap_size);
int i=,key=;
heap_increase_key(arr,i,key,heap_size);//把堆中第i个元素的值改为key值。
max_heap_insert(arr,,heap_size);//插入新值100
show(arr,heap_size);
heapsort(arr,heap_size);
cout<<"after sort and";
show(arr,heap_size);
return ;
}
测试截图:
优先队列/oriority queue 之最大优先队列的实现的更多相关文章
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅰ
许多应用程序都需要处理有序的元素,但不一定要求他们全部有序,或者是不一定要以此就将他们排序.很多情况下我们会手机一些元素,处理当前键值最大的元素,然后再收集更多的元素,再处理当前键值最大的元素.如此这 ...
- C/C++解题常用STL大礼包 含vector,map,set,queue(含优先队列) ,stack的常用用法
每次忘记都去查,真难啊 /* C/C++解题常用STL大礼包 含vector,map,set,queue(含优先队列) ,stack的常用用法 */ /* vector常用用法 */ //头文件 #i ...
- c++ STL queue:deque+优先队列
/* queue 模板类需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque队列 类型.一:定义queue(要有头文件#include <qu ...
- 第二十八篇 玩转数据结构——堆(Heap)和有优先队列(Priority Queue)
1.. 优先队列(Priority Queue) 优先队列与普通队列的区别:普通队列遵循先进先出的原则:优先队列的出队顺序与入队顺序无关,与优先级相关. 优先队列可以使用队列的接口,只是在 ...
- c++ STL:队列queue、优先队列priority queue 的使用
说明:本文全文转载而来,原文链接:http://www.cppblog.com/wanghaiguang/archive/2012/06/05/177644.html C++ Queues(队列) C ...
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅴ
命题Q.对于一个含有N个元素的基于堆叠优先队列,插入元素操作只需要不超过(lgN + 1)次比较,删除最大元素的操作需要不超过2lgN次比较. 证明.由命题P可知,两种操作都需要在根节点和堆底之间移动 ...
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅳ
2.4.4 堆的算法 我们用长度为 N + 1的私有数组pq[]来表示一个大小为N的堆,我们不会使用pq[0],堆元素放在pq[1]至pq[N]中.在排序算法中,我们只能通过私有辅助函数less()和 ...
- 优先队列Priority Queue和堆Heap
对COMP20003中的Priority queue部分进行总结.图片来自于COMP20003 queue队列,顾名思义特点先进先出 priority queue优先队列,出来的顺序按照优先级prio ...
- HDU 4441 Queue Sequence(优先队列+Treap树)(2012 Asia Tianjin Regional Contest)
Problem Description There's a queue obeying the first in first out rule. Each time you can either pu ...
随机推荐
- C++函数的传值调用&指针调用&引用调用
目录 传值调用 指针调用 引用调用 传值调用 该方法把参数的实际值复制给函数的形式参数.在这种情况下,修改函数内的形式参数对实际参数没有影响. #include<iostream> usi ...
- 《ARM Cortex-M3权威指南》笔记(1)
http://blog.csdn.net/roverx/article/details/6624859 第1章 介绍 一.ARM Cortex‐M3处理器初探 CM3处理器内核是单片机的中央处理单元( ...
- Greys--JVM异常诊断工具
https://github.com/oldmanpushcart/greys-anatomy/wiki/greys-pdf 一.简介 我们平时在线上或者开发中会遇到各种性能.功能等问题,在运行过程中 ...
- .net MongoDB使用
.net平台的MongoDB使用 CRL快速开发框架系列教程十二(MongoDB支持) MongoDB数据库 mongo-csharp-driver
- 第75讲:模式匹配下的For循环
今天学习了模式匹配下的for循环内容.让我们从代码实战角度出发. for(i<-List(1,2,3,4,5)) println(i)//实际上调用的是foreach for(in ...
- play framework - 初识
背景 研发代码框架是play-framework框架,想看代码的话,需要学习下play框架.IDE工具的话之前一直用的idea,所以本文涉及的idea play的配置 和 一些play的简单知识 认识 ...
- 作业调度系统quartz.net
任务调度在我们日常开发过程中非常常见,比如:每天晚上0点自动执行某某操作:每周三晚上2点执行某某操作:......当然,我们处理这类问题的方法也有很多,比如:sql的自动任务:windows上创建任务 ...
- win10 17025 触摸bug
This article is written in both English and Chinese. 本文使用中文和英文两个版本. 在 win10 的 17025 可以容易让 UWP 触摸失效.做 ...
- Nginx负载均衡初识
1.背景 nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个HTTP服务器进行网站的发布处理,另外ngi ...
- <meta http-equiv="X-UA-Compatible" content="ie=edge">的意思
<meta http-equiv="X-UA-Compatible" content="ie=edge">vscode创建html文件默认有这串代码 ...