一:堆排序算法
#include <iostream>
#include <math.h>
using namespace std;
#define LEFT(i) (2*(i)+1)
#define RIGHT(i) (2*(i)+2)
// 16(0)
// / \
// 10(1) 8(2)
// / \
// 9(3) 7(4)
//n为5,叶子节点序号为2,3,4 ->floor(5/2).....n
void exchange(int& a,int& b)
{
int tmp=a;
a=b;
b=tmp;
}
void printArray(int a[],int n)
{
for(int i=0;i<n;++i)
cout<<a[i]<<" ";
cout<<endl;
}
void maxHeapify(int a[],int i,int n) // 使以i为根的子树成为最大堆
{
int l=LEFT(i);
int r=RIGHT(i);
int heapindex=n-1;
int largest;
if((l<=heapindex)&&(a[l]>a[i]))
largest=l;
else
largest=i;
if((r<=heapindex)&&(a[r]>a[largest]))
largest=r;
if(largest!=i)
{
exchange(a[i],a[largest]);
maxHeapify(a,largest,n); //由于大小对换了,所以对调的那个有可能就不满足最大堆的性质了
}
}
/* 构建最大堆
数组A[floor(n/2)..n]中的元素都是树中的叶子,所以要对树中的每一个其它节点调用maxHeapify(),让每一个
节点都满足最大堆的性质 ,注意顺序:从最后一个非叶子节点到根*/
void buildMaxHeap(int a[],int n)
{
for(int i=floor(n/2)-1;i>-1;--i)
maxHeapify(a,i,n);
}
/*堆排序
先构建好最大堆,有最大堆性质可知根元素是最大的,把根与最后一个元素交换,让新根调用maxHeapify()
*/
void heapSort(int a[],int n)
{
buildMaxHeap(a,n);
for(int i=n-1;i>0;--i)
{
exchange(a[0],a[i]);
maxHeapify(a,0,i);
}
}
int main()
{
int a[10]={16,4,10,14,7,9,3,2,8,1};
heapSort(a,10);
printArray(a,10);
cout<<endl;
}
运行结果:
1 2 3 4 7 8 9 10 14 16
总结:
1.可以在线性时间内,将一个无序数组建成一个最大堆
2.堆排序时间复杂度为nlgn,但在实践中,快速排序往往优于堆排序
二:实现优先级队列
这里使用基于最大堆实现的最大优先级队列(模拟简单作业调度)
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <math.h>
using namespace std;
#define PARENT(i) ((int)floor(((i)-1)/2)) //堆中节点为i的父节点号(从0开始)
#define LEFT(i) (2*(i)+1)
#define RIGHT(i) (2*(i)+2)
typedef struct job
{
unsigned jobid; //作业号
unsigned pid; //进程pid
char name[10]; //作业name
int priority; //优先级
}*Pjob;
int current=0; //当前索引,从0开始
void exchange(char*& s,char*& d)
{
char *tmp=s;
s=d;
d=tmp;
}
void jobAdd(char **JobTable,Pjob p)
{
int i=current;
JobTable[current]=(char*)p;
while(i>0)
{
if(((Pjob)JobTable[i])->priority > ((Pjob)JobTable[PARENT(i)])->priority) //比较优先级
{
exchange(JobTable[i],JobTable[PARENT(i)]);
i=PARENT(i); //继续和上一级比较
}
else
break;
}
++current;
}
void maxHeapify(char **JobTable,int i) //使以i为根的子树成为最大堆
{
int l=LEFT(i);
int r=RIGHT(i);
int largest=i;
if(l<=current-1&&((Pjob)JobTable[l])->priority > ((Pjob)JobTable[i])->priority)
largest=l;
if(r<=current-1&&((Pjob)JobTable[r])->priority > ((Pjob)JobTable[largest])->priority)
largest=r;
if(largest!=i)
{
exchange(JobTable[i],JobTable[largest]);
maxHeapify(JobTable,largest);
}
}
void doJob(char **JobTable)
{
Pjob now=(Pjob)JobTable[0];
cout<<"作业号:"<<now->jobid
<<" "<<now->name
<<" "<<now->pid
<<" "<<now->priority<<" done!!!"<<endl;
free(JobTable[0]);
--current;
if(current!=0)
{
JobTable[0]=JobTable[current];
maxHeapify(JobTable,0); //交换完后需要重新保持最大堆性质
}
}
int main()
{
char *JobTable[10]={0};
Pjob bash=(Pjob)malloc(sizeof(struct job));
bash->jobid=1;
bash->pid=4321;
strcpy(bash->name,"bash");
bash->priority=12;
Pjob vi=(Pjob)malloc(sizeof(struct job));
vi->jobid=2;
vi->pid=4325;
strcpy(vi->name,"vivi");
vi->priority=16;
Pjob perl=(Pjob)malloc(sizeof(struct job));
perl->jobid=4;
perl->pid=4329;
strcpy(perl->name,"perl");
perl->priority=20;
Pjob qq=(Pjob)malloc(sizeof(struct job));
qq->jobid=3;
qq->pid=4349;
strcpy(qq->name,"qqqq");
qq->priority=30;
Pjob cs=(Pjob)malloc(sizeof(struct job));
cs->jobid=5;
cs->pid=4345;
strcpy(cs->name,"cscs");
cs->priority=18;
jobAdd(JobTable,bash);
jobAdd(JobTable,vi);
jobAdd(JobTable,perl);
jobAdd(JobTable,qq);
jobAdd(JobTable,cs);
doJob(JobTable);
doJob(JobTable);
doJob(JobTable);
doJob(JobTable);
doJob(JobTable);
cout<<endl;
}
运行结果:
作业号:3 qqqq 4349 30 done!!!
作业号:4 perl 4329 20 done!!!
作业号:5 cscs 4345 18 done!!!
作业号:2 vivi 4325 16 done!!!
作业号:1 bash 4321 12 done!!!
基于堆的优先级时间复杂度是lgn。
分享到:
相关推荐
ATHLET程序的钠冷快堆应用扩展及其验证[汇编].pdf
数据结构课设——小大根交替堆实现的双端优先级队列及应用
PINSPEC 项目旨在为核React堆应用的光谱计算提供一个简单易用的 Python 包。 它包括对无限同质光谱计算和异质同质 pin cell 等效计算的支持。 提供了一个基本的 ENDF-VII 连续能量横截面数据库,支持用户为自己的...
javaApps:只是一堆应用程序
利用mfc对话框编写的,数据结构的堆应用
堆排序算法MFC的实现,可直接使用,方便用户
在这个项目中,我将利用我对React的知识,并根据具体的React技术主题构建一堆应用程序,我打算通过专门的项目来展示对本课程的掌握 对应项目 useState 生日提醒请 useEffect和条件渲染 旅游团 评论 手风琴 菜单 ...
二叉堆的概念及其应用,里面包含果子合并、堆排序、鱼塘钓鱼、最小函数值、Sequence等重要题型的详细解析
应用C++编程语言在VC6.0上实现堆排序算法。
从热电偶测温的方法出发, 阐述了热电堆传感器的原理。介绍了它在电测与非电测领域中的应用。 把两种不同金属材料导线的两端连接在一起, 构成闭合环路, 当两个接点有温差时, 则在此回路中存在一个与温差成单调...
用于构建HTML5应用程序的堆 Cordova,用于将该应用程序包装为APK文件(无需Android Studio) 可选:Docker使整个设置自动化 笔记: 欢迎在Github上发表文章,发表评论! 将Heaps编译为本机代码并使用NDK进行构建...
TMP006是一个MEMS数字温度传感器,它是需要远程非接触感应传感器应用中进行热管理和热保护的最优选择。该传感器使用了热电堆来吸收物体发散的红外能量并能够利用热电堆的电压变化来确定物体的温度。 TMP006包括保持...
基于FPGA微型红外热电堆探测器空间应用.pdf
以华为公司产品(HGMP)为例,通过...在当前情况下,普通的级连模式还是解决层次化网络的主要的应用手段,星型堆叠模式是提供单节点端口扩展的简单管理模式,而通过集群管理实现的分布式堆叠将是下一代堆叠的主要方式。
子数据和核数据,加速器和研究堆应用,核技术用于粮食、土壤和牲畜管理,癌症诊 断和治疗,降水中同位素、海洋酸化效应和文化遗产保护研究的新发展。 草案文本已以 GOV/2019/4 号文件提交 2019 年 3 月理事会会议...
java中一堆数组的应用
###5:Dijkstra 使用堆应用 Dijkstra 算法来找到从一个顶点到一个图的所有其他顶点的最短路径。 ###6:TwoSumHashTable 使用哈希表计算给定区间内目标值 t 的数量,使得输入文件中存在满足 x+y=t 的不同数字 x,y ##...
VC调用MATLAB引擎实现核反应堆复杂控制仿真的方法及应用.rar
二叉堆的原理与应用.ppt
c语言 堆和链表 的定义 理解 与使用 方法