定义链队列
"xunhuan.h"
创建一个队列,每个顾客通过该系统得到一个序号,程序将该程序添加到序列中。
柜台的工作人元在处理完一个顾客的业务后,可以选择办理下一位顾客的业务,
程序将从队列的头部获取下一位顾客的序号。
实现流程:
(1)定义DATA数据类型,用于表示进入队列的数据
(2)定义全局变量num,用于保存顾客的序号
(3)编写新增顾客函数add(),为新到顾客生成一个编号,并添加到队列中;
(4)编写柜台工作人员呼叫下一个顾客的函数next();
(5)编写主函数main(),能够根据不同的选择分别调用add()或next()函数来进行对应的操作
typedef struct QNode
{
ElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front; //队头指针,指向队头元素
QueuePtr rear; //队尾指针,指向队尾元素
}LinkQueue;
可以采用顺序表来储存定义的循环队列,使用front指向队列的头元素,用rear指向队尾元素的下一个位置
#define MAXQSIZE 100 //最大队列长度
typedef struct
{
ElemType *base; //储存空间
int front; //头指针,指向队列的元素
int rear; //尾指针,指向队尾元素的下一个位置
}SqQueue; //非增量式的空间分配
队列的基本操作
(1)初始化队列Q,即创建一个队列
void InitQueue(QUEUE *Q)
{
Q->front=-1;
Q->rear=-1;
}
(2)入队,即将一个元素添加到队尾,相当于到队列最后排队等待
void EnQueue(QUEUE *Q,ElemType elem)
{
if((Q->rear+1)%MAX_QUEUE==Q-front)
exit(OVERFLOW);
else
{
Q->rear=(Q->rear+1)%MAX_QUEUE;
Q->elem[Q->rear]=elem;
}
}
(3)出队,即将队头的元素取出,同时删除该元素,使后一个元素成为队头
void DeQueue(QUEUE *Q,ElemType *elem)
{
if(QueueEmpty(*Q))
exit("Queue is empty");
else
{
Q->front=(Q->front+1)%MAX_QUEUE;
*elem=Q->elem[Q->front];
}
}
(4)获取队列第一个元素,即将队头的元素取出,不删除该元素,队头仍是该元素
void GetFront(QUEUE Q,ElemType *elem)
{
if(QueueEmpty(Q))
exit("Queue is empty");
else
{
*elem=Q.elem[(Q.front+1)%MAX_QUEUE];
}
}
(5)判断队列Q是否为空
int QueueEmpty(QUEUE Q)
{
if(Q.front==Q.rear)
return TRUE;
else
return FALSE;
}
队列的链式储存
typedef struct linklist //链式队列的结点结构
{
ElemType Entry; //队列的数据元素类型
struct linklist *next; //指向后继结点的指针
}LINKLIST;
typedef struct queue //链式队列
{
LINKLIST *front; //队头指针
LINKLIST *rear; //队尾指针
}QUEUE;
(1)初始化队列Q
void InitQueue(QUEUE *Q)
{
Q->front=(LINKLIST*)malloc(sizeof(LINKLIST));
if(Q->front==NULL)
exit(ERROR);
Q->rear=Q->front;
}
(2)入队
void EnQueue(QUEUE *Q,ElemType elem)
{
s=(LINKLIST*)malloc(sizeof(LINKLIST));
if(!s)
exit(ERROR);
s->elem=elem;
s->next=NULL;
Q->rear->next=s;
Q->rear=s;
}
(3)出队
void DeQueue(QUEUE *Q,ElemType *elem)
{
if(QueueEmpty(*Q))
exit(ERROR);
else
{
*elem=Q->front->next->elem;
s=Q->front->next;
Q->front->next=s->next;
free(s);
}
}
(4)获取队头元素
void GetFront(QUEUE Q,ElemType *elem)
{
if(QueueEmpty(Q))
exit(ERROR);
else
*elem=Q->front->next->elem;
}
(5)判断队列Q是否为空
int QueueEmpty(QUEUE Q)
{
if(Q->front==Q->rear)
return TRUE;
else return FALSE;
}
演示一个完整的顺序队列的操作过程
//顺序队列操作
#define QUEUEMAX 15
typedef struct
{
DATA data[QUEUEMAX]; //队列数组
int head; //队头
int tail; //队尾
}SqQueue;
SqQueue *SqQueueInit()
{
if(q=(SqQueue *)malloc(sizeof(SqQueue))) //申请保存队列的内存
{
q->head=0; //设置队头
q->tail=0; //设置队尾
return q;
}else
return NULL; //返回空
}
void SqQueueFree(SqQueue *q) //释放队列
{
if(q!=NULL)
free(q);
}
int SqQueueIsEmpty(SqQueue *q) //队列是否为空
{
return (q->head==q->tail);
}
int SqQueueIsFull(SqQueue *q) ///队列是否为满
{
return (q->tail==QUEUEMAX);
}
int SqQueueLen(SqQueue *q) //获取队列长度
{
return (q->tail-q->head);
}
int SqQueueIn(SqQueue *q,DATA data) //顺序队列的入队函数
{
if(q->tail==QUEUEMAX)
{
printf("队列已满!\n");
return(0);
}
else
{
q->data[q->tail++]=data;
return(1);
}
}
DATA *SqQueueOut(SqQueue *q) //顺序队列的出队
{
if(q->head==q->tail)
{
printf("\n队列为空\n");
return NULL;
}
else
{
return &(q->data[q->head++]);
}
}
DATA *SqQueuePeek(SqQueue *q) //获取队头元素
{
if(SqQueueIsEmpty(q))
{
printf("\n队列为空!\n");
return NULL;
}
else
{
return &(q->data[q->head]);
}
}
循环队列的操作
"xunhuan.h"
//循环队列
#define QUEUEMAX 15
typedef struct
{
DATA data[QUEUEMAX]; //队列数组
int head; //队头
int tail; //队尾
}CycQueue;
CycQueue *CycQueueInit()
{
CycQueue *q;
if(q=(CycQueue *)malloc(sizeof(CycQueue))) //申请保存队列的内存
{
q->head=0; //设置队头
q->tail=0; //设置队尾
return q;
}else
return NULL; //返回空
}
void CycQueueFree(CycQueue *q) //释放队列
{
if(q!=NULL)
free(q);
}
int CycQueueIsEmpty(CycQueue *q) //队列是否为空
{
return (q->head==q->tail);
}
int CycQueueIsFull(CycQueue *q) ///队列是否为满
{
return ((q->tail+1)%QUEUEMAX==q->head);
}
int CycQueueIn(CycQueue *q,DATA data) //入队函数
{
if((q->tail+1)%QUEUEMAX==q->head)
{
printf("队列已满!\n");
return 0;
}
else
{
q->tail=(q->tail+1)%QUEUEMAX; //求队尾序号
q->data[q->tail]=data;
return 1;
}
}
DATA *CycQueueOut(CycQueue *q) //循环队列的出队函数
{
if(q->head==q->tail)
{
printf("\n队列为空\n");
return NULL;
}
else
{
q->head=(q->head+1)%QUEUEMAX;
return &(q->data[q->head]);
}
}
int CycQueueLen(CycQueue *q) //获取队列长度
{ int n;
n=q->tail-q->head;
if(n<0)
n=QUEUEMAX+n;
return n;
}
DATA *CycQueuePeek(CycQueue *q) //获取队列中第一个位置的数据
{
if(q->head==q->tail)
{
printf("\n队列为空!\n");
return NULL;
}
else
{
return &(q->data[q->head+4%QUEUEMAX]);
}
}
电信牌号程序
创建一个队列,每个顾客通过该系统得到一个序号,程序将该程序添加到序列中。
柜台的工作人元在处理完一个顾客的业务后,可以选择办理下一位顾客的业务,
程序将从队列的头部获取下一位顾客的序号。
实现流程:
(1)定义DATA数据类型,用于表示进入队列的数据
(2)定义全局变量num,用于保存顾客的序号
(3)编写新增顾客函数add(),为新到顾客生成一个编号,并添加到队列中;
(4)编写柜台工作人员呼叫下一个顾客的函数next();
(5)编写主函数main(),能够根据不同的选择分别调用add()或next()函数来进行对应的操作
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct
{
int num; //顾客编号
long time; //进入队列时间
}DATA;
#include "xunhuan.h"
int num; //顾客序号
void add(CycQueue *q) //新增顾客排列
{
DATA data;
if(!CycQueueIsFull(q)) //如果队列未满
{
data.num=++num;
data.time=time(NULL);
CycQueueIn(q,data);
}
else
printf("\n排队的人太多,请稍后再排队!\n");
}
void next(CycQueue *q) //通知下一个顾客准备
{
DATA *data;
if(!CycQueueIsEmpty(q)) //若队列不为空
{
data=CycQueueOut(q); //取队列头部的数据
printf("\n请编号为%d的顾客办理业务!\n",CycQueueLen(q));
}
if(!CycQueueIsEmpty(q)) //若队列不为空
{
data=CycQueuePeek(q); //取队列中指定位置的数据
printf("请编号为%d的顾客准备,马上将为您办理业务!\n",CycQueueLen(q));
}
}
int main()
{
CycQueue *queue1;
int i,n;
char select;
num=0; //顾客序号
queue1=CycQueueInit(); //初始化队列
if(queue1==NULL)
{
printf("创建队列时出错!\n");
getchar();
return 0;
}
do{
printf("\n请选择具体操作:\n");
printf("1.新到顾客\n");
printf("2.下一个顾客\n");
printf("0.退出\n");
fflush(stdin);
select=getchar();
switch(select)
{
case '1':
add(queue1);
printf("\n选择共有%d位顾客再等候!\n",CycQueueLen(queue1));
break;
case '2':
next(queue1);
printf("\n选择共有%d位顾客再等候!\n",CycQueueLen(queue1));
break;
case '0':
break;
}
}while(select!='0');
CycQueueFree(queue1);
getchar();
return 0;
}