基于堆的优先队列

源代码如下

#include <stdio.h>
#include <stdlib.h>
typedef struct Item *node;
struct Item{
	int data;
	char c;
};
static Item *pq;
static int N ;
void swap(Item &a,Item &b){struct Item t = a;a = b;b = t;}
//自底向上堆化 完全二叉树 父节点的关键值大于等于子节点关键值
void fixUp(Item a[],int k){  //k表示破坏堆规则的位置  O(NlgN)
	while(k>1 && a[k/2].data < a[k].data){
		swap(a[k],a[k/2]);
		k = k/2;
	}
}
//自顶向下堆化
void fixDown(Item a[],int k,int n){  //k表示破坏堆规则关键字的位置 ,n为堆的大小
	int j;
	while(2*k<=n ){
		j = 2*k;
		if(j<n && a[j].data<a[j+1].data)j++; //处理好啦K处节点只有一个子节点的情况
		if(a[k].data>=a[j].data)break;
		swap(a[k],a[j]);
		k = j;
	}
}
void PQinit(int maxN){
	pq = (node)malloc((maxN+1)*sizeof(node));
	N = 0;
}
int PQempty(){
	return N==0;
}
void PQinsert(Item v){
	pq[++N] = v;  //pq[0]未用,在某些实现中可以当作观察哨。
	fixUp(pq,N);
}
Item PQdelmax(){
	swap(pq[1],pq[N]);
	fixDown(pq,1,N-1);
	return pq[N--];
}
main(){
	PQinit(40);
	struct Item a[8] = {{0,'0'},{7,'c'},{95,'c'},{12,'c'},{96,'c'},{76,'c'},{36,'c'},{46,'c'}};
	int j ;
	for(j=1;j<=7;j++) PQinsert(a[j]);
	printf("生成的堆有序的完全二叉树结构\n");
	for(j=0;j<7;j++)
		printf("%d\n",pq[j+1].data);
	printf("逐渐取出优先队列的最大值\n");
	for(j=0;j<7;j++)
		printf("%d\n",PQdelmax().data);
}

运行结果

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 04:02:07

基于堆的优先队列的相关文章

数据结构之基于堆的优先队列

优先队列的最重要的操作:删除最大元素(或最小)和插入元素.数据结构二叉堆能够很好的实现队列的基本操作.二叉堆的结点按照层级顺序放入数组,用长度为N+1的私有数组pq来表示一个大小为N的堆(堆元素放在pq[1]至pq[N]之间,为方便计数,未使用pq[0]),跟节点在位置1,它的子结点在位置2和3,以此类推.位置k的节点的父节点位置为k/2,它的两个子节点位置分别为2k和2k+1.当一颗二叉树的每个节点都大于等于它的两个子节点时,称为大根堆.当一颗二叉树的每个节点都小于等于它的两个子节点时,称为小

0038数据结构之堆和优先队列

优先队列:出队顺序和入队顺序无关,而是和优先级有关(优先级高的先出队) 如果使用普通线性结构或者顺序线性结构实现优先队列,出队或者入队总有一方是O(n)级别的:如果使用堆实现优先队列,能使入队和出队的时间复杂度都是O(logn),效率是极高的. 二叉堆是一颗完全二叉树,不一定是满二叉树,但是确实节点的那部分一定是在整棵树的右下侧.满足的规律:1)根节点最大, 2)确实节点的那部分在整棵树的右下侧.(低层次的节点不一定大于高层次的节点) 下图是一颗最大堆: 可以用数组存储: 从数组1位置开始存储:

堆与优先队列

当我们需要高效的完成以下操作时: 1.插入一个元素 2.取得最小(最大)的数值,并且删除 能够完成这种操作的数据结构叫做优先队列 而能够使用二叉树,完成这种操作的数据结构叫做堆(二叉堆) 堆与优先队列的时间复杂度: 若共有n个元素,则可在O(logn)的时间内完成上述两种操作 堆的结构如下图: 堆最重要的性质就是儿子的值一定不小于父亲的值,且堆从上到下,从左到右紧密排列. 堆的操作: 当我们希望向堆中插入元素时,堆的内部会进行如下操作(以插入元素3为例): (1.在堆的末尾插入该值) (2.不断

堆和优先队列

1 二叉堆和优先队列的概念 1.1 二叉堆 二叉堆堆是一个数组,它可以被看成一个近似的完全二叉树,树上每一个结点对应数组中的一个元素.除了最底层外,该树是完全充满的,而且是从左到右填充.表示堆的数组A包括两个属性:A.length给出数组元素的个数,A.heap_size表示有多少个堆元素存储在该数组中,这里,0<=A.heap_size<=A.length. 如下图所示: 堆可以分成两种:最大堆和最小堆.在最大堆中,任何节点的值都大于等于其孩子的值,故根节点是数组中的最大数所在节点.反之,最

[ACM] POJ 1442 Black Box (堆,优先队列)

Black Box Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7099   Accepted: 2888 Description Our Black Box represents a primitive database. It can save an integer array and has a special i variable. At the initial moment Black Box is empt

基于二叉树的优先队列

简介 优先队列:指队列中的元素都被指派一个优先级,元素按优先级最大(最小)出队,存储堆的数组的第一个元素就是最大的(或最小的).所以用堆作为优先队列的元素载体是合适的. 队列有两个基本操作:1.入队2.出队. 队列的特点是先进先出.通常都把队列比喻成排队买东西,大家都很守秩序,先排队的人就先买东西.但是优先队列有所不同,它不遵循先进先出的规则,而是根据队列中元素的优先权,优先权最大的先被取出.通常把优先队列比喻成现实生活中的打印.一个打印店里有很多打印机,每台机器的性能不一样,有的打印机打印很快

第一篇博客——基于数组的优先队列(java版)

看过园子里和CSND上那么多大牛精彩的博客后,早就按捺不住想亲手写上几篇.奈何每次坐在电脑前准备敲字的时候,立马赶到浑身不自在,无从下手.实在是因为自高考之后,大学以来,本人几乎就再没动笔写过一篇文字,写作水平退化实在严重.今天鼓起勇气开始写作博客,一方面希望通过多写慢慢地找回写作的感觉,一方面也希望通过博客和大家多多交流,共同进步. 既然是第一次试手,就写个简单易懂的内容——优先队列. 话不多说,先上代码. 1 /** 2 * @author Mr Left 3 * @version 1.0

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

队列的特点是先进先出.通常都把队列比喻成排队买东西,大家都很守秩序,先排队的人就先买东西.但是优先队列有所不同,它不遵循先进先出的规则,而是根据队列中元素的优先权,优先权最大的先被取出.这就很像堆的特征:总是移除优先级最高的根节点. 重点:优先级队列,是要看优先级的,谁的优先级更高,谁就先得到权限.不分排队的顺序! 上篇文章解释了堆的概念实现,现在用堆实现优先队列: //最大堆 import java.util.ArrayList; public class Heap<E extends Com

基于堆的最大最小优先级队列的实现

最大堆能够在O(1)的时间内取得集合中的最大值,并且在集合中加入新元素的时候,能够以O(Logn)的时间将新的元素插入到堆中. 当取出最大的元素时,能够以O(Logn)的时间重新将堆整理成最大堆.最小堆同理. 最大优先级队列的应用实例:基于优先级的作业调度,在所有等待调度的作业中,选择具有最大优先级作业进行处理.同时一个新的作业也可以插入到队列里面去. 例如可以实现自己的基于优先级的多线程作业调度程序. 最小优先级队列的应用实例:可以实现一个基于时间的作业调度程序,时间最小的被优先选择进行事件通