本程序实现链队列的入队、出队、显示队头元素、显示所有元素、判断链队列是否为空等操作。
-
队列:先进先出的线性表。队头出队,队尾入队。
-
入队:使用尾插法,即使用尾指针指向最后一个结点。尾插法保证了输入数据与输出数据顺序上 的一致,符合队列先进先出的特点。
-
出队:头指针指向自己指针域的下一个结点,需判断队列是否为空。
#include<stdio.h>
#include<stdlib.h>
/*
本程序的链队列使用带头结点,目的是方便入队、出队操作
头结点:一个不带信息,只有指针域的结点
*/
struct LinkQueue{ //定义链队列结构体
int integer;
struct LinkQueue *next;
};
struct LinkListNode{ //定义指向链队列的结构体
LinkQueue *front,*rear;
};
LinkListNode *InitQueue(); //函数声明,防止无法调用函数
void push(LinkListNode *queue);
void pop(LinkListNode *queue);
int isEmptyQueue(LinkListNode *queue);
void printQueue(LinkListNode *queue);
void printIsEmptyQueue(LinkListNode *queue);
void getQueueTop(LinkListNode *queue);
void menu();
//初始化队列
LinkListNode *InitQueue(){ //动态分配LinkQueue和LinkListNode大小的地址
LinkQueue *node = (LinkQueue *)malloc(sizeof(LinkQueue));
LinkListNode *queue = (LinkListNode *)malloc(sizeof(LinkListNode));
node->next = NULL; //头结点的指针赋为NULL
queue->front = node; //头指针指向node(带头结点)
queue->rear = node; //尾指针指向node
return queue;
}
//入队
void push(LinkListNode *queue){
LinkQueue *s;
int number,i;
printf("输入要入队的元素个数:");
scanf("%d",&number);
printf("输入%d个整数:",number);
for(i = 0; i < number; i++){
s = (LinkQueue *)malloc(sizeof(LinkQueue));
scanf("%d",&s->integer); //新结点的数据赋值
s->next = queue->rear->next; //新结点的指针域指向尾指针的指针域
queue->rear->next = s; //尾指针的指针域指向新结点
queue->rear = s; //尾指针指向新结点
}
getchar(); //吸收换行符,防止main方法的循环自动执行
printf("\n入队成功\n");
}
//出队
void pop(LinkListNode *queue){
LinkQueue *s;
int number;
if(isEmptyQueue(queue)){ //判断队列是否为空
printf("当前队列已空,无法出队\n");
exit(1); //结束程序函数
}
s = queue->front->next; //s指向第一个有值信息的结点
number = s->integer; //把s的数据赋给number
queue->front->next = s->next; //头指针指向第二个有值信息的结点
free(s); //释放s指向的地址空间
//如果只有头结点,使尾指针等于头指针,用于队列判空
if(queue->front->next == NULL)
queue->rear = queue->front;
printf("出队操作成功,出队元素为 %d\n",number);
}
//得到队头元素
void getQueueTop(LinkListNode *queue){
if(isEmptyQueue(queue)){
printf("当前队列已空,无法显示元素\n");
exit(1);
}
//指针变量->头结点->第一个带值结点->带值结点的数据
printf("当前队头元素为 %d\n",queue->front->next->integer);
}
//判断队列是否为空
int isEmptyQueue(LinkListNode *queue){
if(queue->front == queue->rear)
return 1;
else
return 0;
}
//输出队列是否为空
void printIsEmptyQueue(LinkListNode *queue){
if(isEmptyQueue(queue))
printf("当前队列为空\n");
else
printf("当前队列不为空\n");
}
//显示队列所有元素
void printQueue(LinkListNode *queue){
LinkQueue *p = queue->front->next;
if(isEmptyQueue(queue)){
printf("当前队列已空,无法输出元素\n");
exit(1);
}
printf("当前队列为:");
while(p != NULL){
printf("%5d",p->integer);
p = p->next;
}
putchar('\n');
}
//显示菜单
void menu(){
printf("\n 链队列的各种操作");
printf("\n==========================================");
printf("\n| 1--入队 |");
printf("\n| 2--出队 |");
printf("\n| 3--判断队列是否空 |");
printf("\n| 4--得到队头元素 |");
printf("\n| 5--显示队列 |");
printf("\n| 0--退出操作 |");
printf("\n==========================================");
printf("\n输入选择(0~5):");
}
void main(){
LinkListNode *queue;
queue = InitQueue();
char ch1,ch2 = 'y';
do{
menu();
scanf("%c",&ch1);
getchar();
switch(ch1){
case '1':push(queue);break;
case '2':pop(queue);break;
case '3':printIsEmptyQueue(queue);break;
case '4':getQueueTop(queue);break;
case '5':printQueue(queue);break;
case '0':ch2 = 'n';break;
default:printf("选择有误,范围应为0~5\n");
}
if(ch1 != '0'){
printf("按回车键继续,按任意键退出...");
ch1 = getchar();
if(ch1 != '\n'){
getchar();
ch2 = 'n';
}
}
}while(ch2=='y' || ch2=='Y');
printf("\n本次操作结束,");
system("pause"); //输出程序末尾的中文翻译
}