【专题笔记】优先队列和堆

优先队列能够完成以下操作:

♣插入一个数值

♣按照某种条件获得数值,并且删除(如最大值,最小值)

二叉堆的结构:儿子的值一定不小于父亲的值,数的节点按从上到下,从左到右紧密排列。

二叉堆的操作:

♣插入:在堆的末位插入该数值,不断向上交换,直至当前位置的父亲节点小于等于该数值

♣删除:把堆中的最小值(根的位置)删除,把堆最后一个节点移植根的位置,再不断向下交换(如若有两个儿子,选择数值较小的交换),直至当前位置的儿子节点均大于等于它。

二叉堆的存储和普通的二叉树一样,通过数组来存储。我们来分析一下父子的关系:

若父亲所在下标为m,左儿子的下标为n*2+1,右儿子的下标为n*2+2;

若儿子所在的下标为n,父亲的下标为(n-2)/2。

 1 /*最小堆*/
 2 #include<iostream>
 3 #include<cstdio>
 4 using namespace std;
 5 const int MAXN=1000;
 6 int heap[MAXN];
 7 int operate,x,size=-1;
 8
 9 void push()
10 {
11     size++;
12     heap[size]=x;
13     int i=size;
14     while (i>0)
15     {
16         int p=(i-1)/2;
17         if (heap[p]<=x) break;
18         heap[i]=heap[p];
19         i=p;
20     }
21     heap[i]=x;
22     return;
23 }
24
25 void pop()
26 {
27     cout<<heap[0]<<endl;
28     x=heap[size];
29     size--;
30     int i=0;
31     while (i*2+1<size)//表示当前节点至少有一个孩子
32     {
33         int sa=i*2+1,sb=i*2+2;
34         if (heap[sa]>=x && heap[sb]>=x) break;
35         if (sb<size && heap[sa]>heap[sb]) sa=sb;//莫忘在右孩子存在的情形下才执行该判断语句
36         heap[i]=heap[sa];
37         i=sa;
38     }
39     heap[i]=x;
40     return;
41 }
42
43 int main()
44 {
45     while (scanf("%d%d",&operate,&x))
46     {
47         if (operate==0) break;
48         if (operate==1) push();
49         if (operate==2) pop();
50     }
51     return 0;
52 }
时间: 2024-10-25 07:34:57

【专题笔记】优先队列和堆的相关文章

HDU 1058 优先队列or堆

本来应当是一道优先队列或者堆的题 因为每个数都应该是已经得到的数*2 *3 *5 *7而得到的 但是 2*7 大于 3*2 这就必须保证每次取得都是没有拿过的最小的数 但是它主动降低难度在样例里卖了个萌 n的范围是1~5842 而第5842在样例里给出了..所以我们在取出一个数 求出它的*2 *3 *5 *7的时候做一下判断 如果大于最后一位就直接break 因为相乘的顺序在 可以省一点时间 在判断某个数是否出现过的时候 开不出那么大的vis数组 所以直接for循环从ans数组中寻找 所幸没有超

【数据结构】优先队列和堆

优先队列(priority queue) 对于一般的队列是在队列的尾部添加数据,在头部删除,以便先进先出. 而优先队列中的每个元素都有一个优先级,每次将一个元素放入队列中,而每次出队时都是将优先级最大的那个元素出队,称为高进先出(largest-in,first-out). 优先队列必须实现以下几个操作 1.入队(push):将一个元素放入队列中. 2.出队(pop):将优先级最高的元素从队列中删除. 要实现上面的操作可以维护一个有序的链表.每次插入数据时维护整个链表有序,即使用插入法,每次出队

toj 2196 优先队列和堆的用法

很简单的优先队列或者堆的使用. 1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 5 //greater对int来说表示值越小优先级越高,也可以自己定义比较函数 6 priority_queue< int, vector<int>, greater<int> > q; 7 char op[2]; 8 9 int main () 10 { 11 int n; 12 w

JAVA数据结构--优先队列(堆实现)

优先队列(堆)的定义 堆(英语:Heap)是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权.堆即为解决此类问题设计的一种数据结构. 我个人比较通俗的理解就是比如我们平常下载视频看,我们打算下载两部视频,一部2G,一部只有200M.优先队列的思想就是先下载那部体积较小的视频,这样也比较合理,可以下完200M后

优先队列(堆)笔记 c++

当队列中某个对象优先级比其他对象更高时候,需要比其他对象先出队列而不管所在的位置时候,需要使用优先队列. 有如下的实现方法 - 插入在对尾,出队时候遍历整个队列 - 插入时即进行排序,出队时候固定在队首或者对尾 - 使用二叉查找树 - 使用二叉堆 往往在最后的最重要 堆是完全二叉树,使用数组就可以很好的实现.(vector更好,不需要再扩容) template <typename T> class BinaryHeap { public: explicit BinaryHeap(int cap

优先队列(堆)

一.优先队列的一些简单的实现: 1. 使用一个简单的链表在表头以O(1) 执行插入操作,并遍历该链表以删除最小元,这需要O(N) 的时间. 2. 始终让表保持有序状态:这使得插入代价高昂(O(N)), 而删除代价低廉(O(1)).基于删除最小元的操作从不多于插入操作的事实,因此,前者是更好地想法. 3. 使用二叉查找树,它对这两种操作的平均运行时间是O(logN).尽管插入是随机的,而删除不是,但这个结论还是成立的.由于删除的唯一元素是最小元.反复除去左子树中的节点似乎损害树的平衡,使得右子树加

数据结构学习笔记04树(堆 哈夫曼树 并查集)

一.堆(heap) 优先队列(Priority Queue):特殊的“队列”,取出元素的顺序是依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序. 数组 : 插入 — 元素总是插入尾部 ~ O ( 1 ) 删除 — 查找最大(或最小)关键字 ~ O ( n ) 从数组中删去需要移动元素 ~ O( n ) 链表: 插入 — 元素总是插入链表的头部 ~ O ( 1 ) 删除 — 查找最大(或最小)关键字 ~ O ( n ) 删去结点 ~ O( 1 ) 有序数组: 插入 — 找到合适的位置

优先队列(堆实现)

优先队列由二叉堆实现是很普遍的事情. 下面我把二叉堆也称作为堆. 堆是一棵被完全填满的二叉树,一棵高为h的二叉树2h到2h+1-1个节点.这意味着完全二叉树的高时log N. 因为完全二叉树很有规律,所有它可以用一个数组来表示,而不需要指针 对于这棵树,我们可以这样表示. 对于数组中任意一个位置 i 上的元素,其左儿子在位置 2 i 上,右儿子在左儿子后的单元(2 i + 1 ),它的父亲则在位置( i / 2 )上. 1 #ifndef _BinHeap_H 2 3 struct HeapSt

【C/C++学院】0828-STL入门与简介/STL容器概念/容器迭代器仿函数算法STL概念例子/栈队列双端队列优先队列/数据结构堆的概念/红黑树容器

STL入门与简介 #include<iostream> #include <vector>//容器 #include<array>//数组 #include <algorithm>//算法 using namespace std; //实现一个类模板,专门实现打印的功能 template<class T> //类模板实现了方法 class myvectorprint { public: void operator ()(const T &