优先队列

优先队列及应用

﹥>﹥吖頭↗ 提交于 2020-01-24 15:05:21
优先队列及应用 优先队列定义: 能够完成以下操作的数据结构叫做优先队列: 插入一个数值 取出最小或最大值 为实现优先队列,需用到数据结构“ 堆 ” 堆及相关操作 https://blog.csdn.net/qq_45769877/article/details/104077952 但大部分情况并不需要自己实现堆: C++中的STL中priority_queue有优先队列的相关操作 //头文件 # include "queue" using namespace std ; //声明 priority_queue < int > pque ; //进堆 pque . push ( 1 ) ; //堆是否为空 pque . empty ( ) ; //堆头出堆 pque . pop ( ) ; //获得堆顶元素 pque . top ( ) ; //堆的长度 pque . size ( ) ; 有一个问题时:程序默认为大根堆 如何设定大根堆和小根堆:greater()和less()函数 定义:Type为元素类型,Container在STL中默认为vector,Functional 是比较的方式 priority_queue < Type , Container , Functional > //greater()和less()的头文件 # include "functional" #

c语言优先队列的实现

这一生的挚爱 提交于 2020-01-21 18:37:47
优先队列即二叉堆,实现如下: #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> typedef int Element; #define MAX_BINHEAP_LENGTH 10 struct BinaryHeap { Element array[MAX_BINHEAP_LENGTH]; int length; }; int compare(const void* a, const void* b) { // minimul return *(int*)a - *(int*)b; // maximul // return *(int*)b - *(int*)a; } void percolateDown(struct BinaryHeap* heap, int hole) { int child; Element temp = heap->array[hole]; for (; hole * 2 <= heap->length; hole = child) { child = hole * 2; if (child != heap->length && compare(&(heap->array[child + 1]), &(heap->array[child])) < 0)

常见基本的数据结构——优先队列(堆)

有些话、适合烂在心里 提交于 2020-01-19 22:19:01
在多用户环境中,操作系统调度程序必须决定在若干进程中运行那个进程。一般一个进程只能被允许运用一个固定的时间片。一种算法是使用一个队列。开始时作业被放在队列的末尾。调度程度将反复提取队列中的第一个作业并运行它,直到运行完毕或者该作业的时间片被用完,并在作业为被用完时将其放入队列的末尾。但是一般来说,短的作业要尽可能快地结束,这一点很重要,因此在已经被运行的作业中这些短作业应该拥有优先权。此外,有些作业虽然短小但也很重要,也应该拥有优先权。这种特殊的应用似乎需要一些特殊的队列,我们称之为优先队列。 模型 优先队列应该允许至少下面的两种操作,Insert(插入),以及DeleteMin(删除最小值),它的作用是找出,返回和删除优先队列中的最小值。Insert操作相当于队列的入队,DeleteMin操作相当于队列中的出队操作。在贪婪算法中,优先队列也是重要的,因为该算法通过反复的求出最小元来进行计算。 一些简单的实现 使用简单链表可以在表头进行插入并以O(1)的时间复杂度,但是遍历最小元的话则需要O(N)的时间复杂度。另外的一种思路是始终保持排序状态,这使得插入的高昂代价O(N),而DeleteMin的代价是O(1),但是在实际中,DeleteMin的操作次数从不多于插入的操作次数。 还可以使用二叉查找树来实现优先队列,它对这两种操作的时间都是O(logN)

POJ2431Expedition 优先队列

江枫思渺然 提交于 2020-01-18 22:07:19
原题链接 解题思路 在到达加油站 i 时,就获得了一次在之后的任何时候都可以加Bi 单位汽油的权利。每次从优先队列中取出最大的汽油。 · 在经过加油站 i 时,向优先队列中加入Bi · 当燃料箱空时,如果优先队列也是空的,则无法到达终点。否则取出优先队列中最大的元素,给卡车加油 import java.util.Comparator; import java.util.PriorityQueue; import java.util.Queue; import java.util.Scanner; public class POJ2431{ static int[] c = new int[10005]; static int[] d = new int[10005]; static int[] a = new int[10005]; static int[] b = new int[10005]; static int n,L,P; /* static Comparator<Integer> cmp = new Comparator<Integer>() { public int compare(Integer e1, Integer e2) { return e2 - e1; } };*/ public static void main(String[] args) { //

UVA 1153(贪心+优先队列)(选择不重叠区间的变形)

瘦欲@ 提交于 2020-01-17 01:33:09
题意:给定n个工作的需要时间和截止时间,工作只能线性来完成,问最多能完成多少个工作。 题解:容易想到,先将工作根据截止时间排序,截止时间较早者靠前,之后维护一个时间变量cnt和优先队列,若当前工作cnt+q<=d则将q放入优先队列,否则将当前q与priority_queue.top比较,若q小则将top pop掉并push q,并cnt-=queue.top+q从而减少当前所耗时间,从而实现贪心,最后输出priority_queue.size即可。 注意:需要判断!queue.empty,否则会re。 附上AC代码 # include <bits/stdc++.h> # define FOPI freopen("INPUT.TXT", "r", stdin) # define DOPI freopen("OUTPUT.TXT", "w", stdout) # define FOR(i, x, y) for(int i = x; i <= y; i ++) # define ROF(i, x, y) for(int i = x; i >= y; i --) using namespace std ; typedef long long int ll ; const int ind = 0x3f3f3f3f , N = 1e6 + 10 ; const ll inlld =

一步步地分析排序——优先队列和堆排序

断了今生、忘了曾经 提交于 2020-01-15 03:55:00
本文框架 定义和使用场景 优先队列是一个抽象数据类型,和栈、队列类似,它们都是抽象数据类型,相当于一个Java类,有自己的属性,并对外提供API。在了解它有什么API之前,先来看看优先队列的使用场景。 优先队列适用于需要对集合不断地执行插入元素、删除最大(或最小)元素的场景。这个场景大体可以分为两类: 第一类是业务实际情况需要,比如CPU的任务调度,待执行的任务是一个集合,每启动一个新程序就是在向集合里面插入元素。当前程序执行完后,就要从集合里面取出下一个优先级最高的程序。不断地有程序被启动和被执行,就像不断地对集合执行插入、删除最大元素的操作。 第二类场景是“从N个元素里获取最大的M个元素,N很大,不能一次性全部读进内存”,比如从银行成百上千万条交易记录里面找到金额最大的10笔交易;或者从全国的手机号码里面找到使用年限最长的10个号码。对于第二类场景,问题本身并不需要不断地对集合进行插入、删除操作。如果内存没有限制的话,你可以一次性将数据全部装进集合,然后随便选择一个排序算法对集合进行降序排列,接着输出最前面的10个元素。但是由于待处理的数据量过大(相对内存而言),不能使用排序算法解决该类问题,以银行交易记录为例子,你可以用优先队列通过如下步骤解决: 创建一个容量为11的集合 向集合里插入一笔交易记录,如果插入后集合的元素达到11个,删除金额最小的一笔交易( 需要注意的是

40、最小的k个数

穿精又带淫゛_ 提交于 2020-01-08 09:45:47
1、题目描述: 输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。 2、思路: 这道题有三种解法,分别是排序,分治,最大堆(优先队列) 解法一:排序解法,先对输入的数组排序,排序的最快的时间复杂度为o(nlogn),然后取排序后的前k个数。总的时间复杂度为o(nlogn)。 解法二:分治方法,模仿快速排序思想,每次都取数组的第k个数,然后将比第k个数小的数放在数组的左边,比第k个数大的数放在数组的右边。然后不断的调整下去。时间复杂度为O(n)。   这个方法不适合于大数据量,因为需要改变数组的结构,并且要把数组全部加载到内存当中,若内存不够大,就不可以。 解法三:最大堆(优先队列)。首先创建一个容量为k的优先队列,传入比较器,重写其 compare 方法,以保证每次从队列中弹出的元素是最大值。这样优先队列中的元素个数小于k的时候,只需要将数组中取出来的数字直接插入到队列中即可;当优先队列的元素已满,只需要比较堆顶元素和待插入元素,若堆订元素小于待插入元素,那就舍弃,若待插入元素比堆订元素小,那就移除堆订元素,将数组元素插入其中。   这个方法的好处就是不改变数组的结构,内存占用小,适合于海量数据的处理,从最大堆中获取k个数字的最大值的时间复杂度为o(1),而删除和插入元素的操作的时间复杂度为o(logk)

Timer源码之TaskQueue

依然范特西╮ 提交于 2020-01-07 04:49:30
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> TaskQueue类是在Timer文件中的TaskQueue,它是一个又堆实现的优先队列。TaskQueue按任务剩下一次执行时间排序的优先级队列,使用的数据结构是小顶堆(保证堆顶的元素最小) 堆的性质并不保证有序,只是保证能在O(1)找到最小值(小顶堆)或者最大值(大顶堆) 堆本质上是一个完全二叉树,保证了根节点总是比叶子节点大或者小。因为这个优先级队列主要是由来存放TimerTask的,所以它使用的是一个TimerTask的数组来实现的。 import java.util.Arrays; import java.util.TimerTask; class TaskQueue { /** * 使用数组存为,数据是TimerTask类型 */ private TimerTask[] queue = new TimerTask[128]; /** * 任务队列的大小,queue[0]没有使用,queue[1]-queue[size]是排好序的 */ private int size = 0; int size() { return size; } /** * */ TimerTask getMin() { return queue[1]; } TimerTask get(int i) { return queue

栈 队列 优先队列 STL

余生颓废 提交于 2020-01-01 14:36:00
栈 #include<stack> //头文件 stack<char> st; //定义 st.push(str1[0]); //入栈 cur=st.top (); //取栈顶值 st.pop(); //出栈 st.empty ()//空为true 队列 #include<queue> queue<char>que; que.push(a); a=que.front(); que.pop(); que.empty ()优先队列 bool operator < (const coor &a, const coor &b) { return a.time > b.time; //从小到大排序,修改为最小堆,取最小值。 } priority_queue<coor>que; que.push(a); a=que.top();// 默认为最大堆,取最大值。 que.pop(); que.empty () 以下对vector、list、deque容器通用,这里以list容器为例,注意访问元素时vector、deque可用下标直接访问,但对list不行 list<line> dlist; vector<int> c; line in; list<line>::iterator iter;//定义一个指向元素的迭代器 插入: dlist.insert(iter,t)/

栈,队列与优先队列

≯℡__Kan透↙ 提交于 2020-01-01 14:35:42
STL提供3种特殊的数据结构:栈,队列与优先队列 1.栈:符合“后进后出”,有push和pop两种操作 其中push把元素压入栈顶,而pop从栈顶把元素“弹出”。头文件<stack> 声明栈:stack<int>s; #include<iostream> #include<stack> #include<set> #include<vector> #include<map> using namespace std; typedef set<int> myset; map<myset,int> IDcache;//把集合映射成ID vector<myset> Setcache;//根据ID取集合 //查找集合的ID,如果找不到分配一个新ID int ID(myset x) { if(IDcache.count(x)) return IDcache[x]; Setcache.push_back(x); return IDcache[x]=Setcache.size()-1; } #define ALL(x) x.begin(),x.end() #define INS(x) inserter(x,x.begin()) int main() { stack<int> s; int n; cin>>n; for(int i=0;i<n;i++) { string op; cin>>op;