实验七优先队列与堆实验报告

合集下载

堆的应用与实现优先队列堆排序等

堆的应用与实现优先队列堆排序等

堆的应用与实现优先队列堆排序等堆的应用与实现:优先队列、堆排序等堆是一种重要的数据结构,它可以应用于多种场景中,例如优先队列和排序算法。

在本文中,我们将探讨堆的应用以及如何实现优先队列和堆排序。

一、堆的概念与性质堆是一种特殊的完全二叉树,它可以分为最大堆和最小堆两种类型。

最大堆满足父节点的值大于等于子节点的值,而最小堆则相反,父节点的值小于等于子节点的值。

堆具有以下性质:1. 堆总是一棵完全二叉树,即除了最后一层,其他层都是完全填满的。

2. 在最大堆中,任意节点的值都大于等于其子节点的值;在最小堆中,则反之。

3. 堆的根节点是最大值(最大堆)或最小值(最小堆)。

4. 堆的左子节点和右子节点的值相对于父节点的值具有一定的顺序关系。

二、优先队列优先队列是一种特殊的队列,它的出队顺序依赖于元素的优先级而非它们被加入队列的顺序。

堆可以用来实现优先队列。

在堆中,每个元素都有一个优先级,优先级高的元素先出队。

优先队列可以应用于很多场景,例如任务调度、事件处理等。

下面是一个使用堆实现优先队列的伪代码:```class PriorityQueue:def __init__(self):self.heap = []def push(self, item):heapq.heappush(self.heap, item)def pop(self):return heapq.heappop(self.heap)```在上述代码中,我们使用Python中的heapq库来实现堆操作。

通过heappush和heappop函数,我们可以实现元素的入队和出队操作,同时保证堆的特性。

三、堆排序堆排序是一种高效的排序算法,它利用堆数据结构进行排序。

堆排序的基本思想是将待排序序列构建成一个最大堆(或最小堆),然后反复将堆顶元素与最后一个元素交换,并进行调整,直到整个序列有序。

下面是使用堆排序算法对一个数组进行排序的示例代码:```def heapify(arr, n, i):largest = ileft = 2 * i + 1right = 2 * i + 2if left < n and arr[i] < arr[left]:largest = leftif right < n and arr[largest] < arr[right]:largest = rightif largest != i:arr[i], arr[largest] = arr[largest], arr[i]heapify(arr, n, largest)def heap_sort(arr):n = len(arr)for i in range(n // 2 - 1, -1, -1):heapify(arr, n, i)for i in range(n - 1, 0, -1):arr[i], arr[0] = arr[0], arr[i]heapify(arr, i, 0)```在上述代码中,我们首先通过堆化操作将待排序序列构建为一个最大堆。

堆栈模拟队列实验报告

堆栈模拟队列实验报告

一、实验目的通过本次实验,加深对堆栈和队列数据结构的理解,掌握堆栈的基本操作,并学会利用堆栈模拟队列的功能。

通过实验,培养学生的编程能力和问题解决能力。

二、实验内容1. 实现一个顺序堆栈,包括初始化、判断是否为空、入栈、出栈等基本操作。

2. 利用两个顺序堆栈实现队列的功能,包括入队、出队、判断队列是否为空等操作。

3. 通过实例验证模拟队列的正确性。

三、实验原理队列是一种先进先出(FIFO)的数据结构,而堆栈是一种后进先出(LIFO)的数据结构。

本实验通过两个堆栈来实现队列的功能。

当元素入队时,将其压入第一个堆栈(称为栈A);当元素出队时,先从栈A中依次弹出元素并压入第二个堆栈(称为栈B),直到弹出栈A中的第一个元素,即为队首元素。

四、实验步骤1. 定义堆栈的数据结构,包括堆栈的最大容量、当前元素个数、堆栈元素数组等。

2. 实现堆栈的基本操作,包括初始化、判断是否为空、入栈、出栈等。

3. 实现模拟队列的功能,包括入队、出队、判断队列是否为空等。

4. 编写主函数,创建两个堆栈,通过实例验证模拟队列的正确性。

五、实验代码```c#include <stdio.h>#include <stdlib.h>#define MAX_SIZE 100typedef struct {int data[MAX_SIZE];int top;} SeqStack;// 初始化堆栈void InitStack(SeqStack S) {S->top = -1;}// 判断堆栈是否为空int IsEmpty(SeqStack S) {return S->top == -1;}// 入栈int Push(SeqStack S, int x) {if (S->top == MAX_SIZE - 1) { return 0; // 堆栈已满}S->data[++S->top] = x;return 1;}// 出栈int Pop(SeqStack S, int x) {if (IsEmpty(S)) {return 0; // 堆栈为空}x = S->data[S->top--];return 1;}// 队列的入队操作void EnQueue(SeqStack S, SeqStack Q, int x) { Push(S, x);}// 队列的出队操作int DeQueue(SeqStack S, SeqStack Q, int x) { if (IsEmpty(Q)) {while (!IsEmpty(S)) {int temp;Pop(S, &temp);Push(Q, temp);}}if (IsEmpty(Q)) {return 0; // 队列为空}Pop(Q, x);return 1;}int main() {SeqStack S, Q;int x;InitStack(&S);InitStack(&Q);// 测试入队操作EnQueue(&S, &Q, 1);EnQueue(&S, &Q, 2);EnQueue(&S, &Q, 3);// 测试出队操作while (DeQueue(&S, &Q, &x)) {printf("%d ", x);}return 0;}```六、实验结果与分析1. 通过实例验证,模拟队列的入队和出队操作均正确实现了队列的先进先出特性。

数据结构课程实验报告 实验7

数据结构课程实验报告 实验7

HUNAN UNIVERSITY 课程实习报告题目:优先队列与堆学生姓名康小雪学生学号 20090810310专业班级计科三班指导老师李晓鸿完成日期2010-11-5一、需求分析1.本程序可以模拟实现医院排列病人看病的顺序;2.程序要求从键盘输入来看病的病人的顺序和他们的病情的紧急程度,病情越紧急紧急程度的数值越小;3.计算机通过程序将紧急程度按照从小到大的顺序,把看病的病人重新排序,最终得到看病的顺序;4.输入的值每次有两个,病人来的顺序和紧急程度,都是整数;测试用例输入1152 33 5420510-1 -1输出23514二、概要设计抽象数据类型最终出列的顺序是按照priority的值从小到大的顺序排列的,所以,我们考虑用线性表来存储以上的数据,但是,涉及到排序,那么效率最高的应该是优先队列,于是我们可以考虑用最小堆来实现。

ADT PatientList{数据对象patient:patient有ID和priority数据关系R:当前位置pos的左孩子若存在,其位置为2×pos+1;当前位置pos的左孩子存在,其位置为2×pos+2;当前位置pos的父亲存在,其位置为(pos-1)/2;基本操作:void init(PatientList * &PL)操作结果:初始化优先队列void top(PatientList * &PL, patient *p)初始条件:优先队列PL存在操作结果:获得优先队列的队首元素int empty(PatientList *&PL)初始条件:优先队列PL存在操作结果:判断优先队列是否为空void enqueue(PatientList *&PL, int id, int priority)初始条件:优先队列PL存在操作结果:向优先队列中插入一个元素void dequeue(PatientList *&PL)初始条件:优先队列PL存在操作结果:删除有限队列的队首元素算法的基本思想用输入的信息建立最小值堆,再依次删除最小值堆中的最小值,并将其打印出来。

数据结构课程实验报告_实验7优先队列

数据结构课程实验报告_实验7优先队列

HUNAN UNIVERSITY课程实习报告题目:逆波兰表达式问题优先队列与堆学生姓名学生学号指导老师完成日期2015-5-9逆波兰表达式问题实验背景在工资管理软件中,不可避免的要用到公式的定义及求值等问题。

对于数学表达式的计算,虽然可以直接对表达式进行扫描并按照优先级逐步计算,但也可以将中缀表达式转换为逆波兰表达式,这样更容易处理。

基本要求使用二叉树来实现。

实现提示利用二叉树后序遍历来实现表达式的转换,同时可以使用实验3的结果来求解后缀表达式的值。

输入输出格式:输入:在字符界面上输入一个中缀表达式,回车表示结束。

输出:如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。

测试用例输入:21+23*(12-6)输出:21 23 12 6 -*+源代码:#include<iostream>#include<string>#include<iomanip>using namespace std;char str[100][15];//由于一个数字可能有多个数字组成int search_1(int start,int end)//寻找优先级最小的'+'或‘-’{int i,count=0,pos=-1;//count用来记录括号的数量,pos用来记录优先级最小的'+'或'-'的位置for(i=start;i<end;i++){if(str[i][0]=='(')count++;else if(str[i][0]==')')count--;else if((str[i][0]=='+' || str[i][0]=='-') && count==0)//无括号时pos=i;//i记录的是优先级最小的'+'或'-'的位置,也就是没有括号,并且在后面的加减运算}return pos;}int search_2(int start ,int end)//寻找优先级最小的‘*’或‘/’的位置{int i,count=0,pos=-1;//count用来记录括号的数量,pos用来记录优先级最小的'+'或'-'的位置for(i=start;i<end;i++){if(str[i][0]==')')count--;else if(str[i][0]=='(')count++;else if((str[i][0]=='*' || str[i][0]=='/') && count==0)pos=i;}return pos;}double turn(char c[]) //将字符串中的数字转换为浮点型{double temp=0;int i;for(i=0;;i++){if(c[i]!='\0')temp=temp*10+c[i]-'0';elsebreak;}return temp;}class Node{public:char data[15];Node* lchild;Node* rchild;Node(){lchild=NULL;rchild=NULL;}};class Bintree{public:Node* subroot;Node* creattree(int start ,int end);//建立二叉树void postorder(Node* subroot); //后续遍历二叉树double calcute(Node* subroot); //计算表达式的结果void destory(Node* subroot); //销毁二叉树,释放空间};Node* Bintree::creattree(int start,int end)//用递归的方法来建立二叉树{int pos=-1;Node* root =new Node;if(end-start==1)strcpy(root->data,str[start]);else{pos=search_1(start,end); //找优先级最低的加减法if(pos==-1)pos=search_2(start,end);//如果没有的话那就找优先级最低的乘除法if(pos==-1)root=creattree(start+1,end-1);else{strcpy(root->data,str[pos]);root->lchild=creattree(start,pos);root->rchild=creattree(pos+1,end);}}return root;}void Bintree::postorder(Node* subroot)//递归的方法后续遍历{if(subroot!=NULL){postorder(subroot->lchild);postorder(subroot->rchild);cout<<subroot->data<<" ";}}void Bintree::destory(Node *subroot){if(subroot!=NULL){destory(subroot->lchild);destory(subroot->rchild);}delete (subroot);}double Bintree::calcute(Node* subroot)//计算表达式的结果{double result;if(subroot->lchild==NULL && subroot->rchild==NULL) //递归出口,返回值{result=turn(subroot->data);return result;}switch(subroot->data[0]){case'+':return calcute(subroot->lchild)+calcute(subroot->rchild);break;case'-':return calcute(subroot->lchild)-calcute(subroot->rchild);break;case'*':return calcute(subroot->lchild)*calcute(subroot->rchild);break;case'/':return calcute(subroot->lchild)/calcute(subroot->rchild);break;}}int main(){char a[100];Bintree tree;Node* subroot;int i=0,count=0;bool flag=0;cout<<"请输入表达式:"<<endl;while(cin>>a){int j=0;while(a[i]!=0){if(a[i]=='+' || a[i]=='-' || a[i]=='/' || a[i]=='*'){if(flag){cout<<"表达式错误"<<endl; //判断表达式是否正确,即是否有多个运算符连续输入goto loop;}str[j++][0]=a[i++];flag=1;}else if(a[i]=='(' || a[i]==')'){str[j++][0]=a[i];if(a[i++]=='(')count++;elsecount--;if(count<0){cout<<"表达式错误"<<endl;//判断括号是否匹配goto loop;}}else{int k=0;while(a[i]!='+' && a[i]!='-' && a[i]!='*' && a[i]!='/' && a[i]!=')' && a[i]!='(' && a[i]!=0 )str[j][k++]=a[i++];j++;flag=0;}}if(count!=0){cout<<"表达式错误"<<endl;goto loop;}subroot=tree.creattree(0,j);tree.postorder(subroot);cout<<endl;cout<<"表达式的值:"<<endl;cout<<fixed<<setprecision(2)<<tree.calcute(subroot)<<endl;tree.destory(subroot);loop:{i=0;count=0;flag=0;}}return 0;}运行结果:优先队列与堆一、需求分析1.本程序可以模拟实现医院排列病人看病的顺序;2.程序要求从键盘输入来看病的病人的顺序和他们的病情的紧急程度,病情越紧急紧急程度的数值越小;3.计算机通过程序将紧急程度按照从小到大的顺序,把看病的病人重新排序,最终得到看病的顺序;4.输入的值每次有两个,病人来的顺序和紧急程度,都是整数,以-1,-1输入作为结束符;测试用例输入1152 33 5420510-1 -1输出23514二、概要设计抽象数据类型最终出列的顺序是按照priority的值从小到大的顺序排列的,所以,我们考虑用所输入的权值构建最小值堆来实现。

优先队列的实验报告

优先队列的实验报告

一、实验目的1. 理解优先队列的基本概念和特点。

2. 掌握优先队列的常用实现方法,如数组实现、链表实现等。

3. 通过编程实现优先队列,并测试其功能。

4. 了解优先队列在实际应用中的优势。

二、实验内容1. 优先队列的基本概念和特点2. 优先队列的实现方法3. 优先队列的应用实例4. 优先队列的性能分析三、实验环境1. 操作系统:Windows 102. 编程语言:Java3. 开发工具:Eclipse四、实验过程1. 优先队列的基本概念和特点优先队列是一种特殊的队列,它支持在队列中存储元素的同时,能够根据元素的优先级来高效地检索出具有最高优先级的元素。

优先队列的特点如下:(1)非空:优先队列中至少包含一个元素。

(2)元素有序:优先队列中的元素按照优先级排序,最高优先级的元素排在队列的前端。

(3)高效检索:在优先队列中检索具有最高优先级的元素的时间复杂度为O(1)。

2. 优先队列的实现方法优先队列的常用实现方法有数组实现和链表实现。

(1)数组实现:使用数组存储元素,根据元素优先级进行排序。

当需要检索最高优先级的元素时,只需访问数组的第一个元素即可。

(2)链表实现:使用链表存储元素,链表中的节点包含元素和优先级信息。

检索最高优先级的元素时,需要遍历链表,时间复杂度为O(n)。

本实验采用数组实现优先队列。

3. 优先队列的应用实例以下是一个使用优先队列实现的冒泡排序算法示例:```javapublic class BubbleSort {public static void sort(int[] arr) {PriorityQueue<Integer> pq = new PriorityQueue<>();for (int i = 0; i < arr.length; i++) {pq.offer(arr[i]);}int index = 0;while (!pq.isEmpty()) {arr[index++] = pq.poll();}}}```4. 优先队列的性能分析(1)时间复杂度:对于数组实现,插入、删除和检索最高优先级元素的时间复杂度均为O(log n)。

数据结构实验报告 栈和队列

数据结构实验报告 栈和队列

数据结构实验报告栈和队列
栈(Stack)和队列(Queue)都是常用的数据结构。

它们都是有限的数据存储结构,主要用于记录数据的存储和检索。

它们具有许多相同的特征,可以根据每一个实例的需要而定制遍历,并可以使用相同的存储方法。

但是,从数据操作和操作数据的角度来看,它们仍有差异。

首先,栈和队列的数据操作模式不同。

栈是遵循“先进后出”(LIFO)的原则,只有最后一个元素可以被弹出或者取出;而队列则是遵循“先进先出”(FIFO)的原则,第一个元素是最先被取出或弹出的。

此外,栈不允许插入新元素,而队列允许任何位置插入和删除元素。

此外,栈只能被依次访问,而队列允许改变已有元素的位置。

此外,栈和队列可以用相似的实现方式来构建。

一般来说,它们都使用 .链表,数组或者树来存储数据,并使用相同的Pointers来指向数据结构中的元素。

栈和队列也可以使用交换的方式来改变其存储方式,从而提高其效率。

对于实际应用来说,栈和队列都有自己的优势,具体取决于应用中的需求。

比如,栈通常被用于数据的深度优先遍历,而队列则可以用于数据的广度优先遍历。

此外,栈也可以用于处理函数调用,而队列可以用于处理操作系统任务或者打印池中的任务等。

优先队列与堆数据结构实验报告

优先队列与堆数据结构实验报告

优先队列与堆问题描述:假设某医生看病人的顺序是由病人的病情严重程度来决定。

护士按照所有病人来医院的时间顺序给病人编号ID,依次为1,2,3,…,n;并且根据病人的病情严重程度设置Priority值,病越重,Priority的值越小。

当医生开始工作时,护士根据病人的Priority值,由小到大依次安排病人看病。

试为护士编写程序安排病人看病的先后次序。

基本要求:(1)利用最小值堆实现一个优先队列。

(2)对于优先队列应该支持如下操作:初始化队列的init操作;获得队列中元素个数的size操作;判定队列是否为空的empty操作;获得队列中最优先的元素的值的top操作;向队列中插入一个元素的push操作;删除队列中最优先的元素的pop操作。

(3)利用优先队列存入所有病人的信息(编号和病情严重程度)。

最后利用优先队列获得病人看病的次序。

需求分析:1、输入形式:输入文件的每一行有两个整数index和value,分别表示病人的ID和Priority 值,病越重,Priority的值越小。

最后一行数据以-1 -1 结束,相应的这组数据不应处理2、输出形式:将病人的看病优先序列输出,每个病人的数据占一行,只需输出其ID。

3、功能描述:使得每一个病人都能够公平公正的得到看病的合法次序,为医院解决秩序问题,更好地为病人服务。

4、输入输出样例:输入:1 152 33 54 205 10-1 -1输出:235145、效率分析:O(log(n))抽象数据结构类型:数据结构类型描述:typedef struct {int id; .// 病人的ID编号int value; // 病人病情的严重程度}PriorityQueue;优先队列的基本操作:void Init_Queue() function:初始化队列void insert_Queue(PriorityQueue q) function:将元素q插入优先队列中的合适位值int del_Queue() function:删除队列头的元素,并返回其IDV oid Empty_Queue() function:判断队列是否为空队列概要设计:优先队列是基于堆的思想来实现的,相应的插入、删除、以及对优先队列的维护都是通过堆的思想来实现的,而在很实验中我是通过对堆的数组表示后改造为队列的,其本质思想都是相通的,都是基于堆的思想来实现快速的查询工作!详细设计:主题思想是通过分块、分步的方法设计的:1、void Init_Queue() function: 初始化队列2、void insert_Queue(PriorityQueue q) function:将元素q插入优先队列中的合适位值3、int del_Queue() function:删除队列头的元素,并返回其ID4、V oid Empty_Queue() function:判断队列是否为空队列5、在main()调用上述函数来实现程序的功能实现提示:(1)最小值堆采用数组作为物理存储结构,每个元素是一个结构体变量,包含编号ID和病情严重程度Priority值。

堆与优先队列了解堆的性质和优先队列的应用

堆与优先队列了解堆的性质和优先队列的应用

堆与优先队列了解堆的性质和优先队列的应用堆与优先队列:了解堆的性质和优先队列的应用在计算机科学中,堆(Heap)是一种常见的数据结构,用于解决许多实际问题,特别是在优先级队列的实现中。

本文将介绍堆的性质以及优先队列在实际问题中的应用。

一、堆的性质堆是一种特殊的完全二叉树,它具有以下性质:1. 完全二叉树:堆是一个完全二叉树,除了最后一层外,其它层的节点数都达到了最大值,最后一层的节点从左至右排列。

2. 堆序性:对于大顶堆(MaxHeap)来说,父节点的值大于或等于其子节点的值;对于小顶堆(MinHeap)来说,父节点的值小于或等于其子节点的值。

堆可以通过数组或二叉树来表示,其中数组表示是最常用的方法。

在数组表示中,父节点与子节点之间的关系可以通过索引的方式来表示,这种方式使得堆的操作更加高效。

二、优先队列优先队列是一种特殊的队列,其中每个元素都有一个优先级。

与普通队列不同的是,在优先队列中,具有较高优先级的元素优先出队列。

优先队列可以使用堆来实现,具体来说,可以使用小顶堆或大顶堆来构建优先队列。

在使用堆实现优先队列时,我们根据元素的优先级将其插入到堆中,并且可以随时删除最高(最低)优先级的元素。

优先队列的应用非常广泛,比如:1. 任务调度:在操作系统中,可以使用优先队列来调度不同优先级的任务,优先级高的任务将被优先处理。

2. 网络路由:在路由器中,优先队列可以用于选择最佳路径,从而提高网络的传输效率。

3. 模拟系统:在模拟系统中,优先队列可以用于按照优先级处理事件,使得模拟结果更接近真实情况。

4. 数据压缩:在哈夫曼编码等数据压缩算法中,优先队列可以用于选择出现频率最高的字符。

总之,优先队列的应用涉及各个领域,其高效的实现依赖于堆这一数据结构。

结论通过对堆的性质和优先队列的应用的介绍,我们可以充分了解到堆在计算机科学中的重要性。

堆的性质使得我们可以高效地实现优先队列,从而解决许多实际问题。

希望本文对读者进一步了解堆和优先队列有所帮助,并可以在实际应用中灵活运用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验报告部分
HUNAN UNIVERSITY 课程实习报告
题目:优先队列与堆
学生姓名廖嘉琦
学生学号 20090820109 专业班级通信一班
指导老师夏艳
完成日期 2010-11-2
一、需求分析
(1)本程序要求利用最小值堆实现一个优先队列。

(2)对于优先队列应该支持如下操作:初始化队列的init操作;获得队列中元素个数的size操作;判定队列是否为空的empty操作;获得队列中最优先的元素的值的top 操作;向队列中插入一个元素的push操作;删除队列中最优先的元素的pop操作。

(3)利用优先队列存入所有病人的信息(编号和病情严重程度)。

最后利用优先队列获得病人看病的次序。

(4)堆的数组的ID和和Priority由用户通过键盘输入,其取值范围为(0,216)。

不对非法输入做处理,即假设输入都是合法的。

(5)在Dos界面输出病人看病的次序。

(6)测试数据
输入
115
2 3
3 5
420
510
-1 -1
输出
2
3
5
1
4
二、概要设计
抽象数据类型
为实现上述程序的功能,应以整数存储用户的输入,以及计算出的结果。

算法的基本思想
(1)根据题目要求,最小值堆采用数组作为物理存储结构,每个元素是一个结构体变量,包含编号ID和病情严重程度Priority值,以Priority进行排序,最后由优先队列获得病人看病的次序。

程序的流程
程序由三个模块组成:
(1)输入模块:完成输入结构体数组中每个元素的ID和Priority节点个数,存储在struct patient p[30]中。

(2)处理模块:再定义一个类,将该数组作为参数传给类,使数组变成一个优先队列。

(3)输出模块:屏幕上显示排序后的病人看病次序。

三、详细设计
物理数据类型
题目要求输入的正整数的取值范围在(0,216)之间,为了能够存储,采用C语言中的整型定义变量。

在定义一个结构体变量,存储次序和病情程度。

struct patient {
int ID;
int Priority; };
算法的具体步骤算法流程图如下
输入和输出的格式
输入
615
7 3
8 5
920
1010 //输入病人的ID号和Priority
-1 -1 //以-1结束
输出
2
3
5
1
4 //输出病人的次序
四、调试分析
略。

五、测试结果
输入
1115
12 3
13 5
1420
1510
-1 -1
输出
2
3
5
1
4
六、用户使用说明(可选)
1、本程序的运行环境为DOS操作系统,执行文件为正式实验七.exe
2、运行程序时
提示输入病人的ID号和Priority
以-1结束
七、实验心得(可选)
略。

七、附录(可选)
正式试验七.c 主程序
#include<iostream.h>
struct patient
{
int ID;
int Priority;
}; //定义一个结构体变量
class minheap
{
private:
struct patient* Heap;
int size;
int n;
void siftdown(int);
public:
minheap(struct patient * h,int num,int max) //包涵该数组、数组元素数目、数组的大小{
Heap=h;
n=num;
size=max;
buildHeap(); //建立一个最小值堆
}
int heapsize() const { return n;} //堆的大小
bool isLeaf (int pos) const
{ return (pos >=n/2)&&(pos<n); } //判断是否叶节点
int leftchild(int pos) const
{ return 2*pos+1; } //得到左节点
int rightchild(int pos) const
{ return 2*pos+2; } //得到右节点
int parent(int pos) const
{ return (pos-1)/2; } //得到父节点
bool empty()
{ if(n==0) return true; else return false;} //判定队列是否为空
bool push(const struct patient&); //向队列中插入一个元素
bool pop(struct patient&); //删除队列中最优先的元素bool top(struct patient&); //获得队列中最优先的元素的值
void buildHeap()
{ for(int i=n/2-1;i>=0;i--) siftdown(i); } //将一个数组按照堆的性质重新建立
};
void minheap::siftdown(int pos) //往下建立最小值堆
{
while (!isLeaf(pos))
{
int j = leftchild(pos);
int rc = rightchild(pos);
if ((rc<n) && (Heap[j].Priority>Heap[rc].Priority))
j = rc; //先把Heap[j]设成子树中的较小值
if (!(Heap[pos].Priority>Heap[j].Priority))
return; //结点若比子树还小,就不必动
struct patient temp;
temp=Heap[pos];
Heap[pos]=Heap[j];
Heap[j]=temp; //交换结点与该子树
//swap(Heap, pos, j);
pos = j; //把子树设为当前结点,再重复进行,往下建立最小值堆}
}
bool minheap:: pop(struct patient& it) //删除队列中最优先的元素
{
if (empty()) return false; // 堆是空的
struct patient temp;
temp=Heap[0];
Heap[0]=Heap[--n];
Heap[n]=temp; //把堆中的最小元素与最后一个元素交换
//swap(Heap, 0, --n);
if (n != 0)
siftdown(0); //将第一个元素往后交换
it = Heap[n]; // 返回最小元素
return true;
}
bool minheap::push (const struct patient& val) //向队列中插入一个元素
{
if(n>=size)
return false; //堆已满
int curr=n++;
Heap[curr]=val;
while((curr!=0)&&(Heap[curr].Priority<Heap[parent(curr)].Priority))
{
struct patient temp;
temp=Heap[curr];
Heap[curr]=Heap[parent(curr)];
Heap[parent(curr)]=temp;
//swap(Heap,curr,);
curr=parent(curr);
} //按照优先值把元素插入堆中
return true;
}
bool minheap::top(struct patient& it)
{
if(n==0)
return false ;
it=Heap[0]; //返回第一个元素,即最优先元素
return true;
}
void main()
{
cout<<"请输入病人的ID号和病情程度,并以-1结束"<<endl;
int a,b;
cin>>a;
cin>>b;
struct patient p[30]; //定义一个结构体数组
int i=0;
while((a!=-1)&&(b!=-1)) //如果a和b都不是-1,继续往下{
p[i].ID=a; //对结构体变量的初始化
p[i].Priority=b;
i++;
cin>>a;
cin>>b;
} //最后数组中一共有i个值
minheap dui(p,i,30); //建立一个类,使得该数组成为一个堆
struct patient patient1;
cout<<"病人的排序为:"<<endl;
for(int j=0;j<i;j++)
{
dui.pop(patient1);
cout<<patient1.ID<<endl; //打印出排序后病人的ID }}。

相关文档
最新文档