队列是一种先进先出的线性表,只允许在一端插入另一端删除元素。对头删除,对尾插入元素。
队列的有两种存储结构:链式存储结构和循环顺序存储结构。
本篇主要记录队列的单链存储结构实现
#include
#ifndef STATUS_H
#define STATUS_H
/* 状态码 */
#define TRUE 1 //真
#define FALSE 0 //假
#define YES 1 //是
#define NO 0 //否
#define OK 1 //通过
#define ERROR 0 //错误
#define SUCCESS 1 //成功
#define UNSUCCESS 0 //失败
#define INFEASIBLE -1 //不可行
#ifndef _MATH_H_ //系统中已有此状态码定义,要避免冲突
#define OVERFLOW -2 //堆栈上溢
#define UNDERFLOW -3 //堆栈下溢
#endif
#ifndef NULL
#define NULL ((void*)0)
#endif
/* 状态码识别类型 */
typedef int Status;
//定义结构体
typedef char QElemType; /* QElemType类型根据实际情况而定,这里假设为char */
typedef struct QNode{/* 结点结构 */
QElemType data;
struct QNode *next;
}QNode, *QueuePtr;
typedef struct{ /* 队列的链表结构 */
QueuePtr front;/* 队头、队尾指针 */
QueuePtr rear;
}LinkQueue;
//基本操作的函数原型说明
//构造一个空队列
void InitQueue(LinkQueue *Q);
//销毁队列,Q不存在
Status DestoryQueue(LinkQueue *Q);
//将Q清为空队列
Status ClearQueue(LinkQueue *Q);
//若Q为空队列,则返回TURE,否则返回FALSE
Status EmptyQueue(LinkQueue Q);
//队列长度
int QueueLength(LinkQueue Q);
//队列不为空,用e返回队列的头元素,并返回OK,否则返回ERROR
Status GetHead(LinkQueue Q, QElemType *e);
//掺入元素e为Q的新对尾元素
Status EnQueue(LinkQueue *Q, QElemType e);
//队列不为空时,删除Q的队列头元素,用e返回其值,并返回OK, 否则返回ERROR
Status DeQueue(LinkQueue *Q, QElemType *e);
//从对头到对尾依次调用visit函数,失败的话,则操作失败。
Status QueueTraverse(LinkQueue Q, Status(*Visit)());
//操作队列的方法
//初始化单链队列
void InitQueue(LinkQueue *Q){
Q->front= Q->rear = (QueuePtr)malloc(sizeof(QNode));
if(!Q->front)
exit(OVERFLOW);
Q->front->next= NULL;
return OK;
}
//销毁单链队列
Status DestoryQueue(LinkQueue *Q){
while(Q->front){
Q->rear=Q->front->next;
free(Q->front);
Q->front= Q->rear;
}
return OK;
}
//判断单链队列是否为空
Status EmptyQueue(LinkQueue Q){
if(Q.front==NULL && Q.rear==NULL){
return TRUE;
} else{
return FALSE;
}
}
//在对尾插入新的元素
Status EnQueue(LinkQueue *Q, QElemType e){
//给指针分配内存
QueuePtr q;
q = (QueuePtr)malloc(sizeof(QNode));
if(!q)
exit(OVERFLOW);
q->data = e;
q->next=NULL;
Q->rear->next=q;
Q->rear=q;
return OK;
}
//队列长度
int QueueLength(LinkQueue Q){
int i = 0;
if(Q.front==NULL)
exit(OVERFLOW);
QueuePtr q;
q = Q.front->next;
while(q){
++i;
q = q->next;
}
return i;
}
//打印队列元素
Status QueueTraverse(LinkQueue Q, Status(*Visit)()){
QueuePtr q;
if(Q.front==NULL)
exit(OVERFLOW);
q = Q.front->next;
while(q){
printf(" %d", q->data);
q = q->next;
}
return OK;
}
//删除队列头元素
Status DeQueue(LinkQueue *Q, QElemType *e){
QueuePtr q;
if(Q->front==NULL)
exit(OVERFLOW);
q = Q->front->next;
*e = q->data;
Q->front->next = q->next;
if(Q->rear==q)
Q->rear=Q->front;
free(q);
return OK;
}
//获取队列头元素
Status GetHead(LinkQueue Q, QElemType *e){
QueuePtr q;
if(Q.front==NULL)
exit(OVERFLOW);
q = Q.front->next;
*e = q->data;
return OK;
}
Status ClearQueue(LinkQueue *Q){
while(Q->front->next!=NULL){
Q->rear=Q->front->next;
Q->front->next=Q->rear->next;
free(Q->rear);
Q->rear=Q->front->next;
}
Q->rear=Q->front;
return OK;
}
//主函数体
void PrintElem(QElemType e);
int main(int argc, char **argv){
LinkQueue Q;
int i = 0;
QElemType e;
//初始化队列
printf("初始化队列Q...\n\n");
InitQueue(&Q);
//判断队列是否为空
EmptyQueue(Q) ? printf("队列为空!!\n\n") : printf("队列不为空!\n\n");
//往队列插入0-9个数---为Q的新的队尾元素
for (i=0; i<=10; i++){
EnQueue(&Q, i);
}
//判断队列是否为空
EmptyQueue(Q) ? printf("队列为空!!\n\n") : printf("队列不为空!\n\n");
//队列长度
printf("队列长度%d\n\n", QueueLength(Q));
//打印数列
printf("打印队列元素:");
QueueTraverse(Q, PrintElem);
printf("\n\n");
//打印队列长度
printf("队列长队为%d\n\n", QueueLength(Q));
//删除对头元素,用e返回
DeQueue(&Q, &e);
printf("删除的对头元素为%d\n\n", e);
printf("队列长队为%d\n\n", QueueLength(Q));
DeQueue(&Q, &e);
printf("删除的对头元素为%d\n\n", e);
printf("队列长队为%d\n\n", QueueLength(Q));
//获取对头元素,用e返回
GetHead(Q, &e);
printf("获取到的对头元素为%d\n\n", e);
ClearQueue(&Q);
printf("队列长度%d\n\n", QueueLength(Q));
DestoryQueue(&Q);
EmptyQueue(Q) ? printf("队列为空!!\n\n") : printf("队列不为空!\n\n");
return 0;
}
void PrintElem(QElemType e){
printf("%d ", e);
}