上次插了个链栈,发现链队列还没有插上来,现在一并附上。
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR -1
#define OVERFLOW -2
const int MAXSIZE = 80; // 预设的存储空间最大容量
typedef int Status;
typedef int QElemType;
//*************************************************************************//
// 采用链式结构实现队列处理时,规定
// 1、设置2个指针,分别保存对头和队尾,当对头和队尾相都为空时,队列为空;
// 2、插入数据时,在对头插入
// 3、删除数据时,在队尾删除
//*************************************************************************//
typedef struct Node //队列结点定义
{
QElemType data;
struct Node *next;
}QNode, *QueuePtr;
typedef struct //链队列类型
{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
//功能:初始化队列(本质就是创建一个空链表)
//实现:申请1个结点空间(即链表表头),使队列的front和rear指向该结点
// 由于该队列最开始的时候是空队列,因此,使得front->next为空
Status InitLinkQueue(LinkQueue &Q)
{
Q.front = Q.rear = (QueuePtr)malloc( sizeof(QNode) ); //创建链表表头,并使Q.front 和 Q.rear指针指向该表头结点
if(!Q.front)
return ERROR;
Q.front->next = NULL; //空链表
return OK;
}
//功能:队列数据的插入和单链表的尾部插入算法完全一致。
int EnQueue(LinkQueue &Q, QElemType e)
{
QueuePtr p; //新结点指针
p = (QueuePtr)malloc(sizeof (QNode));
if (!p) //存储分配失败
exit (OVERFLOW);
p->data = e; //队尾插入
p->next = NULL;
Q.rear->next = p; //修改尾部指针
Q.rear = p; //新结点变成尾结点(即队尾)
return OK;
}
//功能:队列删除是在队头删除,因此,只需要修改单链表表头指针的指向即可
Status DeQueue(LinkQueue &Q, QElemType &e)
{
// 若队列不空,则删除Q的队头元素,用 e 返回其值,并返回OK;否则返回ERROR
QueuePtr p;
if (Q.front == Q.rear) //或是Q.front->next == NULLL
return ERROR;
p = Q.front->next; //删除的原则:对头删除
e = p->data;
Q.front->next = p->next; //修改单链表表头指针的指向
if(Q.rear == p) //判断是否删除元素后是队列是否为空
Q.rear = Q.front;
free (p);
return OK;
}
//功能:输出链队列中的所有数据
void OutputQueue(LinkQueue Q)
{
int i = 0;
QueuePtr p;
if (Q.front == Q.rear) //或是Q.front->next == NULLL
printf("队列中数据个数为:0 !\n");
else
{
printf("对头到对尾的数据分别是:\n");
p = Q.front->next;
while(p)
{
i++;
printf(" 第 %d 个数据是:%d\n", i, p->data);
p = p->next;
}
printf("队列数据的总数:%d \n", i);
}
}
//功能:清空链队列的所有数据
Status EmptyQueue(LinkQueue &Q)
{
QueuePtr p, q;
if (Q.front == Q.rear) //或是Q.front->next == NULLL,空队列,无需清除数据
return OK;
else
{
p = Q.front->next;
while(p)
{
q = p;
p = p->next;
free(q);
}
Q.front->next = NULL; //使指针指向空
Q.rear = Q.front;
return OK;
}
}
void ShowMenu()
{
printf("\n");
printf("\n****************链队列基本操作****************\n\n");
printf("\t\t1 队列清空\n");
printf("\t\t2 队列数据输出\n");
printf("\t\t3 数据入队列\n");
printf("\t\t4 数据出队列\n");
printf("\t\t0 退出系统\n");
printf("\n****************链队列基本操作****************\n\n");
printf("\n");
}
int main()
{
int choice;
QElemType e;
LinkQueue Q; //定义一个队列
InitLinkQueue( Q ); //初始化队列
while(1)
{
ShowMenu();
printf("Please choose: ");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
printf("严重警告:清空队列会造成队列中的数据丢失!\n");
if(EmptyQueue(Q) == OK)
printf("队列数据清除成功,当前队列为空队列!\n");
else
printf("队列数据清除失败,当前队列为空或队列中的数据正在被其它程序使用!\n");
printf("press any key to continue....\n");
getchar(); getchar(); system("CLS");
break;
}
case 2:
{
OutputQueue(Q);
printf("press any key to continue....\n");
getchar(); getchar(); system("CLS");
break;
}
case 3:
{
printf("入队列数据:");
scanf("%d", &e);
EnQueue(Q, e);
printf("press any key to continue....\n");
getchar(); getchar(); system("CLS");
break;
}
case 4:
{
if(DeQueue(Q, e) == OK)
printf("当前出队列的数据是:%d \n", e);
else
printf("队列为空,无法出队列!\n");
printf("press any key to continue....\n");
getchar(); getchar(); system("CLS");
break;
}
case 0:
{
system("CLS");
printf("Thanks for using the softeware!\n");
exit(0);
}
default:
{
printf("功能选择错误,只能选择0-5.\n");
printf("press any key to continue....\n");
getchar(); getchar(); system("CLS");
}
}
}
return 0;
}