【算法设计-优先队列】优先队列的实现与操作

优先队列是堆排序的一个具体应用。

优先队列分为如下几个操作:

1.INSERT(S,x)把元素x插入到优先队列中。

2.MAXIMUM(S):返回s中具有最大关键字的元素。

3.EXTRACT_MAX(S):去掉S中最大关键字的元素

4.INCREASE_KEY(S,x,k):将元素x的关键字值增加到k,k是不小于x的元素。

优先队列的应用:

1.共享计算机系统的作业调度。最大优先队列要i记录要执行的各个作业以及他们之间的相对优先级。当一个作业完成或者被中断后,调度器调用EXTRACT_MAX从所有的等待作业中,选出具有最高优先级的作业来执行。在任何时候调度器可以调用INSERT把一个新作业假如到队列中来。

2.可以用于最小生成树和单元最短路径优先算法中,需要应用DECREASE_KEY的应用。

代码:

/*

Author:Bai

Name:优先队列

Use for:1.共享计算机系统中的作业调度

2.基于事件驱动的模拟器

3.用在最小生成树和单元最短路径中

Date:2015/4/30

*/

#include<iostream>

using namespace std;

typedef struct heap

{

int heap_size;

int *key;

}heap;

void initialize(heap *A)

{

A->key=new int;

A->heap_size=0;

}

void MAX_HEAPIFY(heap *A,int i)//为了使堆保持大根堆的性质(我这里利用了循环操作的方法,而算法导论中应用了递归调用的办法)

{

//非递归方法

int largest;

int l=2*i;//l是A的左孩子

int r=2*i+1;//r是A的右孩子

if(l<=A->heap_size&&A->key[l]>A->key[i])//这里的大于号更改成小于号就是小根堆排序

largest=l;

else

largest=i;

if(r<=A->heap_size&&A->key[r]>A->key[largest])

largest=r;

while(largest!=i)

{

int temp=A->key[i];

A->key[i]=A->key[largest];

A->key[largest]=temp;

i=largest;

l=2*i;

r=2*i+1;

if(l<=A->heap_size&&A->key[l]>A->key[i])

largest=l;

else

largest=i;

if(r<=A->heap_size&&A->key[r]>A->key[largest])

largest=r;

}

for(int k=1;k<=A->heap_size;k++)

printf("%d,",A->key[k]);

printf("\n");

}

void BUILD_MAX_HEAP(heap *A)

{

int m=(A->heap_size)/2;

while(m>=1)

{

MAX_HEAPIFY(A,m);

m--;

}

}

void HEAP_SORT(heap *A)

{

BUILD_MAX_HEAP(A);

printf("第一次建立大根堆后的数组是:");

for(int k=1;k<=A->heap_size;k++)

printf("%d,",A->key[k]);

printf("\n");

int length=A->heap_size;

printf("大根堆排序后的数组是:");

printf("%d,",A->key[1]);

for(int i=length;i>=2;i--)

{

A->key[1]=A->key[i];

A->heap_size--;

MAX_HEAPIFY(A,1);//现在只有这个堆的第一个结点是错误的,其他的子树都是大根堆

printf("%d ",A->key[1]);

}

printf("\n");

printf("done\n");

}

//求优先队列的最大值

int HEAP_MAXIMUM(heap *A)

{

printf("%d\n",A->key[1]);

return 0;

}

//将优先队列中去除最大值

void HEAP_EXTRACT_MAX(heap *A)

{

if(A->heap_size<1)

printf("不能再继续删除了!\n");

A->key[1]=A->key[A->heap_size];

A->heap_size--;

MAX_HEAPIFY(A,1);

}

//将优先队列中的某个数m增大到key,key>m

void HEAP_INCREASE_KEY(heap *A,int i,int key)

{

A->key[i]=key;

int parent=i/2;

while(i>1&&A->key[i]>A->key[parent])//这个点增大后,要向上判断其是否比父节点大,然后依次循环修改。

{

int temp=A->key[i];

A->key[i]=A->key[parent];

A->key[parent]=temp;

i=parent;

parent=i/2;

}

}

//将key这个值插入到A优先队列

//首先建立一个新的结点,然后将它赋值为负无穷大,最后再利用HEAP_INCREASE_KEY将它增大到key。

void HEAP_INSERT(heap *A,int key)

{

A->heap_size=A->heap_size+1;

A->key[A->heap_size]=INT_MIN;

HEAP_INCREASE_KEY(A,A->heap_size,key);

}

void SHOW_HEAP(heap *A)

{

printf("当前的优先队列是:\n");

for(int i=1;i<=A->heap_size;i++)

printf("%d ",A->key[i]);

printf("\n");

}

int main(void)

{

int ch;

heap *A=new heap;

initialize(A);

printf("请输入一组堆的值以#结束?\n");

int key;

int i=1;

while(scanf("%d",&key)==1)

{

HEAP_INSERT(A,key);//插入的过程会自动创建称为优先队列

}

fflush(stdin);

while(1)

{

printf("***************请选择如下操作选项***************\n");

printf("1.取优先队列的最大值\n");

printf("2.去除优先队列当前的最大值,去除后仍然自动变换为优先队列结构\n");

printf("3.插入某个值,插入后仍然自动变换为优先队列结构\n");

printf("4.把某个i点上的值增大到key\n");

printf("5.退出系统\n");

scanf("%d",&ch);

switch(ch)

{

case 1:HEAP_MAXIMUM(A);break;

case 2:

HEAP_EXTRACT_MAX(A);

break;

case 3:

{

int key;

printf("请输入您要插入的Key值:");

scanf("%d",&key);

HEAP_INSERT(A,key);

}

SHOW_HEAP(A);

break;

case 4:

{

printf("请问您要把第几个数变成多大?:");

int i,key;

scanf("%d %d",&i,&key);

HEAP_INCREASE_KEY(A,i,key);

}

SHOW_HEAP(A);

break;

case 5:

return 0;

default: break;

}

}

}

结果展示:

时间: 2024-10-06 04:55:11

【算法设计-优先队列】优先队列的实现与操作的相关文章

最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind

最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小支撑树(minimum spanning tree)算法.给定一个无向图G,并且它的每条边均权值,则MST是一个包括G的所有顶点及边的子集的图,这个子集保证图是连通的,并且子集中所有边的权值之和为所有子集中最小的. 本节中介绍三种算法求解图的最小生成树:Prim算法.Kruskal算法和Boruvk

AACOS:基于编译器和操作系统内核的算法设计与实现

AACOS:基于编译器和操作系统内核的算法设计与实现 [计算机科学技术] 谢晓啸 湖北省沙市中学 [关键词]: 编译原理,操作系统内核实现,算法与数据结构,算法优化 0.索引 1.引论 1.1研究内容 1.2研究目的 1.3研究提要 正文 2.1研究方法 2.2编译器部分 2.2.1从计算器程序中得到的编译器制作启示 2.2.2在编译器中其它具体代码的实现 2.2.3编译器中栈的高级应用 2.2.3编译器中树的高级应用 2.2.4编译器与有限状态机 2.3操作系统内核部分 2.3.1操作系统与底

数据结构与算法分析(六)——算法设计技巧

从算法的实现向算法的设计转变,提供解决问题的思路 1.贪心算法 一种局部最优算法设计思路,思想是保证每一步选择在当前达到最优.一个很常见的贪心算法案例是零钱找取问题. 调度问题:书上的调度问题比较简单,其目标是所有作业的平均持续时间(调度+运行)最短,无论是但处理器还是多处理器,最优解的方案总是按作业的长短排序进行调度.<计算机算法设计与分析>上的作业调度的目标是最后完成时间最小,这要稍微复杂一些. 霍夫曼编码:最优编码必定保持满树的性质,基本问题在于找到总之最小的满二叉树.最简单的霍夫曼编码

算法设计与分析 - 李春葆 - 第二版 - pdf-&gt;word v3

1 1.1 第1章─概论 2 3 1.1.1 练习题 4 1. 下列关于算法的说法中正确的有( ). 5 Ⅰ.求解某一类问题的算法是唯一的 6 Ⅱ.算法必须在有限步操作之后停止 7 Ⅲ.算法的每一步操作必须是明确的,不能有歧义或含义模糊 8 Ⅳ.算法执行后一定产生确定的结果 9 A. 1个 B.2个 C.3个 D.4个 10 2. T(n)表示当输入规模为n时的算法效率,以下算法效率最优的是( ). 11 A.T(n)= T(n-1)+1,T(1)=1 B.T(n)= 2n2 12 C.T(n)

算法设计与分析基础(第3版)读书笔记(及几处翻译上的错误~~)

算法设计与分析基础(第3版) p16 in-place翻译为'在位'?'就地'更合适点 p38 amortized应翻译为'均摊','摊销'这个词简直莫名其妙(可能因为翻译是做算法交易导致的?) p64 迭代优于递归(迭代始终是增量式的,而递归就没办法增量了,除非能够dump整个运行时栈) p73 通过算法可视化得到一个更好的非递归算法(人的图像认知直觉思维?) p79 验证一个拓扑是环.星.还是团?(这个地方有点意思,因为我想到了动态的Verify) p87 凸包问题:从数据结构上讲,Set<

【转载】算法设计之五大常用算法设计方法总结

转载自http://blog.csdn.net/zolalad/article/details/11393915 算法设计之五大常用算法设计方法总结 一.[分治法]  在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)--等.任

算法设计原则

在平时的工作中遇到纯粹的算法设计的工作内容并不多,但是算法在编程中的重要性是不言而喻的,再怎么拔高算法的地位都不为过. 那么在设计算法中有什么可以遵循的原则吗? 答案是有的,算法在设计的过程中可以遵循如下五个原则. 1.穷举算法思想 穷举算法思想就是从所有的可能结果中一个一个的试验,知道试出正确的结果.具体的操作步骤如下: 1)对每一种可能的结果,计算其结果: 2)判断结果是否符合题目要求,如果符合则该结果正确,如果不符合则继续进行第1)步骤. 穷举算法思想的经典例子为鸡兔同笼为题(又称龟鹤同笼

从数组循环左移问题中浅谈考研算法设计的规范代码

问题:设将n(n>1)个整数存放到一维数组R中.设计一个算法,将R中的序列循环左移p(0<p<n)个位置,即将R中的数据由{X0,X1,...,Xn-1}变换为{Xp,Xp+1,...,Xn-1,X0,X1,...,Xp-1}.要求:写出本题的算法描述. 分析: 本题不难,要实现R中序列循环左移p个位置,只需先将R中前p个元素逆置,再将剩下的元素逆置,最后整体逆置操作即可.本题算法描述如下: 1 #include <iostream> 2 using namespace st

算法设计方法:递归的内涵与经典应用

摘要: 大师 L. Peter Deutsch 说过:To Iterate is Human, to Recurse, Divine.中文译为:人理解迭代,神理解递归.毋庸置疑地,递归确实是一个奇妙的思维方式.对一些简单的递归问题,我们总是惊叹于递归描述问题的能力和编写代码的简洁,但要想真正领悟递归的精髓.灵活地运用递归思想来解决问题却并不是一件容易的事情.本文剖析了递归的思想内涵,分析了递归与循环的联系与区别,给出了递归的应用场景和一些典型应用,并利用递归和非递归的方式解决了包括阶乘.斐波那契