3.33③ 在顺序存储结构上实现输出受限的双端循环队列的入列和出列(只允许队头出列)算法。设每个元素表示一个待处理的作业,元素值表示作业的预计时间。入队列采取简化的短作业优先原则,若一个新提交的作业的预计执行时间小于队头和队尾作业的平均时间,则插入在队头,否则插入在队尾。
实验六 2、 完成数据结构题集P26中的3.33算法设计,并写程序验证。
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define OVERFLOW -2
#define ERROR -1
#define MAXQSIZE 100
//顺序存储双端循环队列 !!!!!!!顺序存储!!!!!!
typedef struct{
double *base;
int front;
int rear;
}SqQueue; // 相当于base是基地址,front和rear是下标
int InitQueue(SqQueue &Q)
{
Q.base=(double *)malloc(MAXQSIZE*sizeof(double));
if(!Q.base)exit(OVERFLOW);
Q.front=Q.rear=0;
return OK;
}//初始化
int EnQueue(SqQueue &Q,double e){
if((Q.rear+1)%MAXQSIZE==Q.front)return ERROR;//这个不是链表,所以通过下标关系来确定“位置关系” ,这是通过空出一个位置来判断空还是满
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE; //实际上在内存中队列并没有实现循环,只是通过对下标的处理来实现循环存储
return OK;
} //队尾插入
int BeQueue(SqQueue &Q,double e){
if((Q.rear+1)%MAXQSIZE==Q.front)return ERROR;
Q.front=(Q.front-1+MAXQSIZE)%MAXQSIZE;
Q.base[Q.front]=e;
} //队头插入
int DeQueue(SqQueue &Q,double &e)
{
if(Q.front==Q.rear) return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
} //删除队头元素
int main()
{
SqQueue Q;
double e;
InitQueue(Q);
printf("请依次输入要处理的作业时间(输入-1停止):\n");
scanf("%lf",&e);
while(e!=-1)
{
if(Q.rear-Q.front==0)
{
EnQueue(Q,e);
}else if(Q.rear-Q.front==1){
if(e>=Q.base[Q.front])
{
EnQueue(Q,e);
}else{
BeQueue(Q,e);
}
}else{
if(e<(Q.base[Q.front]+Q.base[(Q.rear-1+MAXQSIZE)%MAXQSIZE])/2)
{
BeQueue(Q,e);
}else{
EnQueue(Q,e);
}
}
scanf("%lf",&e);
}
printf("出队列:\n") ;
while(Q.front!=Q.rear)
{
DeQueue(Q,e);
printf("%lf\n",e);
}
return 0;
}