1、优先队列与堆实验报告附c+源码优先队列与堆(病人看病顺序)一、需求分析1.本程序采用最小值堆实现一个优先队列,最小值堆是用的数组实现;2.优先队列支持如下操作:初始化队列的初始化操作(在构建对象的时候实现);获得队列中元素个数;判定队列是否为空;获得队列中最优先的元素的值;向队列中插入一个元素;删除队列中最有先的元素;3.优先队列中,存有病人的信息(编号和病情严重程度),此程序4.测试数据:输入:编号1 严重程度1编号2 严重程度2编号3 严重程度3编号4 严重程度4编号5 严重程度5-1 -1输出:编号2 编号1 编号5 编号4 编号3二、概要设计抽象数据类型构建了一个病人信息类,只用于存储
2、病人信息(编号,病情严重程度):class Nodepublic: int ID; /记录病人编号 int Priority; /记录病人病情严重程度;构建了一个最小值堆类,采用数组实现,成员变量、函数详细信息如下:class MinHeapprivate: Node* heap; /根结点,也是数组头元素的地址 int maxSize,num;/maxSize为堆元素最多个数,num记录元素个数 void siftdown(int);/将结点移动到符合要求的位置 void swap(Node&,Node&);/交换两结点的值public: MinHeap(int); bool isEmpty
3、();/判断堆是否为空 bool isLeaf(int);/判断是不是叶结点 bool push(const Node);/插入结点 bool pop(Node&);/删除根结点 int top();/返回根结点的ID int l_ChildPos(int);/获得左结点的位置 int r_ChildPos(int);/获得右结点的位置 int parentPos(int);/获得妇结点的位置;算法的基本思想1.最小值堆采用数组作为物理存储结构,每个元素是一个结构体变量,包含编号ID和病情严重程度Priority值;2.用户输入一个病人信息,就用插入法,插进堆里,输入完毕时,就是一个符合要求的
4、堆3.用户录入1 1表示输入结束;4.输出:每输出一个最小值,就删掉一个,然后继续整理成最小值堆,继续输出。程序的流程初始化一个空堆-插入病人信息到合适位置-当堆不为空,输出最小值,删掉最小值,直到堆为空。算法的具体步骤1.输入病人信息,构建成堆:每输入一个病人信息,就将该病人信息移至堆中合适位置bool MinHeap:push(const Node in)/向堆里插入结点 if(nummaxSize) return false; int curr=num+; heapcurr=in; while(curr!=0)&heapcurr.PriorityheapparentPos(curr).P
5、riority) swap(heapcurr,heapparentPos(curr); curr=parentPos(curr); return true;2.输出根结点的值,并删除根结点,直到堆为空:bool MinHeap:pop(Node &it) /删除根结点 if(num=0) return false; swap(heap0,heap-num); if(num!=0)siftdown(0); /因为最后一个元素与根结点交换值,需要将根/结点移到合适位置,实现如下 it=heapnum; return true;将某位置的结点向下移到合适位置的函数:void MinHeap:sift
6、down(int pos) /将pos上的结点移到合适的位置 while(!isLeaf(pos) int l=l_ChildPos(pos),r=r_ChildPos(pos); if(rheapr.Priority) l=r; if(heapl.Priority=heappos.Priority) return; swap(heapl,heappos); pos=l; 算法的时空分析因为使用的是插入法建堆,每次插入,有可能要从数的底部移动到顶部,因此,最差情况下时间代价为(n),插入n个病人信息的时间代价为(nn)。在删除结点后,需要将根结点向下移到合适位置,最坏的情况移动的最大距离为移到
7、底部,时间复杂度为(n)。输入和输出的格式 输入 输入“-1 -1”结束输入 /提示 等待输入 输出 编号按病情排序结果 /提示 输出结果三、测试结果 四、用户使用说明1.需要输入“-1 -1”结束输入;2.默认最大的病人信息量为40个。五、实验心得 这个实验比较简单,因为可以参考书上的算法和源码。但还是有出错的地方,就是在使用数组时,只定义了一个与数组类型相同的指针,就将那指针做数组名使用,因此编译出错。六、附录(源码)#includeusing namespace std;class Nodepublic: int ID; int Priority;class MinHeapprivate
8、: Node* heap; /根结点 int maxSize,num;/maxSize为该堆的做多元素个数,num记录当前堆里结点数目 void siftdown(int);/将结点移动到符合要求的位置 void swap(Node&,Node&);/交换两结点的值public: MinHeap(int); bool isEmpty();/判断堆是否为空 bool isLeaf(int);/判断是不是叶结点 bool push(const Node);/插入结点 bool pop(Node&);/删除根结点 int l_ChildPos(int);/获得左结点的位置 int r_ChildPo
9、s(int);/获得右结点的位置 int parentPos(int);/获得妇结点的位置;MinHeap:MinHeap(int size) /构造函数 heap=new Nodesize; num=0; maxSize=size;bool MinHeap:isEmpty() /判断是否为空 if(num!=0) return false; return true;int MinHeap:l_ChildPos(int pos)/获得左结点的位置 return 2*pos+1;int MinHeap:r_ChildPos(int pos)/获得右结点的位置 return 2*pos+2;int
10、 MinHeap:parentPos(int pos)/获得父结点的位置 return (pos-1)/2;void MinHeap:swap(Node& aNode,Node& bNode)/交换两个结点的值 Node temp; temp=aNode; aNode=bNode; bNode=temp;bool MinHeap:isLeaf(int pos)/判断是否为叶结点 return (pos=num/2)&(posmaxSize) return false; int curr=num+; heapcurr=in; while(curr!=0)&heapcurr.Priorityhea
11、pparentPos(curr).Priority) swap(heapcurr,heapparentPos(curr); curr=parentPos(curr); return true;bool MinHeap:pop(Node &it) /删除根结点 if(num=0) return false; swap(heap0,heap-num); if(num!=0) siftdown(0); it=heapnum; return true;void MinHeap:siftdown(int pos) /将pos上的结点移到合适的位置 while(!isLeaf(pos) int l=l_C
12、hildPos(pos),r=r_ChildPos(pos); if(rheapr.Priority) l=r; if(heapl.Priority=heappos.Priority) return; swap(heapl,heappos); pos=l; int main() Node temp; MinHeap oneHeap(40); cout 输入-1 -1结束输入 temp.ID temp.Priority; if(temp.ID=-1&temp.Priority=-1) break; oneHeap.push(temp); cout 编号按病情排序结果: endl; while(!oneHeap.isEmpty() oneHeap.pop(temp); cout temp.ID t; cout endl; return 0;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1