特殊线性表队的c语言,数据结构之守规矩的先进先出的队列(二)

一、队列的概念

队列是一种特殊的线性表,严格按照“先进先出”的原则。

二、队列基础

队列和栈一样只允许在断点处插入和删除元素,其基本操作包括以下:

(1)InitQueue(&Q);    //初始化一个空队列

(2)DestroyQueue(&Q);   //清空队列

(3)QueueEmpty(&Q);  //队列判空

(4)QueueLength(&Q); //求队列的长度

(5)GetHead(Q,&e); //取对头元素

(6)EnQueue(&Q,e); //插入新元素

(7)DeQueue(&Q,&e); //删除队头元素

(8)QueueTraverse(Q,visit()); //每个元素调用visit()函数

队列的分类:链队列和循环队列

C语言定义链队的格式

typedef structQNode

{

ElemType data;struct Qnode *next;

}QNode,*QueuePtr;

typedefstruct{

QueuePtr front;//对头指针,指向头元素

QueuePtr rear; //队尾指针,指向队尾元素

}LinkQueue;

可以采用顺序表来存储定义循环队列,具体代码如下:

#define MAXQSIZE 100 //最长队列长度typedefstruct{

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->reasr + 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是否为空

intQueueEmpty(Queue Q)

{if (Q.front==Q.rear)

{returnTRUE;

}else{returnFALSE;

}

}

队列的链式存储

在C语言中,链式队列的基本操作算法如下:

(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;

Q->front = (Q->front + 1) %MAX_QUEUE;free(s);

}

}

(4)获取队头元素

void GetFront(QUEUE Q, Elemtype *elem)

{if(QueueEmpty(Q))

{

exit(ERROR);

}else{*elem = Q->front->next->elem;

}

}

(5)判断队列Q是否为空

voidQueueEmpty(QUEUE Q)

{if (Q->front==Q->rear)

{returnTRUE;

}else{returnFALSE;

}

}

三、实例演练

“新增顾客”编号问题

代码实现:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*构建一个完整循环队列*/#include"stdio.h"#include"malloc.h"

#define QUEUEMAX 15

//typedef DATA;

typedef struct{

DATA data[QUEUEMAX];//队列数组

inthead;inttail;

}CycQueue;

CycQueue*CycQueueInit()

{

CycQueue*q;if (q=(CycQueue *)malloc(sizeof(CycQueue)))

{

q->head = 0;//设置队头

q->tail = 0;//设置队尾

returnq;

}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("队列满了!");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("队列为空了!");returnNULL;

}else{

q->head = (q->head + 1) %QUEUEMAX;return &(q->data[q->head]);

}

}int CycQueueLen(CycQueue *q) //获取队列长度

{intn;

n= q->tail - q->head;if (n<0)

{

n= QUEUEMAX +n;

}returnn;

}

DATA*CycQueuePeek(CycQueue *q) //获取队列第一个位置的数据

{if (q->head==q->tail)

{

printf("队列已经空了!");returnNULL;

}else{return &(q->data[(q->head + 1) %QUEUEMAX]);

}

}

##############################################

#include"stdlib.h"#include"stdio.h"#include"time.h"#include"xuncao.h"typedefstruct{int num; //顾客编号

long time; //进入队列的时间

}DATA;int num; //顾客序号

void add(CycQueue *q) //新增顾客排列

{

DATA data;if (!CycQueueIsFull(q))

{

data.num= ++num;

data.time=time(NULL);

CycQueueIn(q, data);

}else{

printf("排队的人实在是太多了,请您稍候再排队!");

}

}void next(CycQueue *q) //通知下一位顾客准备

{

DATA*data;if (!CycQueueIsEmpty(q)) //若队列不为空

{

data= CycQueueOut(q); //取队列头部的数据

printf("欢迎编号为%d的顾客到柜台办理业务!", data->num);

}if (!CycQueueIsEmpty(q)) //若队列不为空

{

data= CycQueuePeek(q); //取队列中指定位置的数据

printf("请编号为%d的顾客做好准备,马上将为您办理业务!", data->num);

}

}intmain()

{

CycQueue*queuel;inti, n;char select;

num= 0; //顾客序号

queuel = CycQueueInit();//初始化队列

if (queuel==NULL)

{

printf("创建队列时出错误!");

getch();return 0;

}do{

printf("请选择具体操作:");

printf("1.新到顾客");

printf("2.下一个顾客");

printf("0.退出");

fflush(stdin);select =getch();switch (select)

{case'1':

add(queuel);

printf("现在共有%d位顾客在等候!", CycQueueLen(queuel));break;case'2':

next(queuel);

printf("现在共有%d位顾客在等候!", CycQueueLen(queuel));break;case'0':break;

}

}while (select!='0');

CycQueueFree(queuel);//释放队列

system("pause");return 0;

}

代码实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值