C语言实现链队基本操作(以简单排队问题为例)
通过调用简单函数实现顺序表的相关操作。代码编译环境为VS2019 16.9.4。因为VS的某些原因,scanf写为了scanf_s,作用是一样的,在其他编译环境中可将scanf_s改回去。
建议运行后体验(理论上,在空间充足的情况下链队不会出现队满的情况,所以队满不考虑,链队的关键是两种结构体的定义,一种是链表结点,另一种是链队结点):
#include<stdio.h> //输入输出头文件
#include<stdlib.h> //标准头文件
#include<stdbool.h> //布尔类型头文件
typedef long long int Elemtype; //该队列中的元素为字符
typedef struct LinkQuene* SqList; //将该队列类型的指针命名为SqList
typedef struct Quene* List; //将该队列类型的指针命名为SqList
struct Quene //定义结点
{
Elemtype data; //存放队列中的数据元素
List next; //下一个结点指针
};
struct LinkQuene
{
List front; //指向队首结点
List rear; //指向队尾结点
};
bool InitQuene(SqList& q); //初始化队列
bool DestroyQuene(SqList& q); //销毁队列
bool QueneEmpty(SqList& q); //判断队列是否为空
bool enQuene(SqList& q, Elemtype e); //进队列
bool deQuene(SqList& q, Elemtype& e); //出队列
void menu(void); //主界面
void menu1(void); //店长菜单
void menu2(void); //顾客菜单
int main(int argc, const char* argv[])
{
SqList q;
Elemtype e;
bool flag = false;
int n, m;
InitQuene(q);
menu();
while (scanf_s("%d", &n) != EOF) {
if (n == 0) //退出
break;
if (n == 1) {
menu1();
scanf_s("%d", &m);
while (m != 0) {
switch (m) {
case 1:flag = deQuene(q, e);
if (flag)
printf("%lld已取餐。\n", e);
else
printf("当前没有顾客,出餐失败。\n");
break;
case 2:flag = QueneEmpty(q);
if (flag)
printf("当前无人排队,可以休息了。\n");
else
printf("顾客正在等待。\n");
break;
default:
printf("指令错误,请重新输入。\n");
}
menu1();
scanf_s("%d", &m);
}
}
else if (n == 2) {
printf("请输入您的会员号(不超十位的整数):");
scanf_s("%lld", &e);
menu2();
scanf_s("%d", &m);
while (m != 0) {
switch (m) {
case 1:flag = enQuene(q, e);
if (flag)
printf("预定成功。\n");
break;
case 2:flag = QueneEmpty(q);
if (flag)
printf("当前无人排队,你很幸运。\n");
else
printf("前方仍有其他顾客在排队。\n");
break;
default:
printf("指令错误,请重新输入。\n");
}
menu2();
scanf_s("%d", &m);
}
}
else
printf("指令错误,请重新输入。\n");
menu();
}
DestroyQuene(q);
return 0;
}
void menu(void)
{
printf("==========================\n");
printf("=======选择您的身份=======\n");
printf("== ==\n");
printf("== 1.商家 ==\n");
printf("== 2.客户 ==\n");
printf("== 0.退出系统 ==\n");
printf("== ==\n");
printf("==========================\n");
}
void menu1(void)
{
printf("==========================\n");
printf("=========店长你好=========\n");
printf("== ==\n");
printf("== 1.出餐 ==\n");
printf("== 2.是否有人等餐 ==\n");
printf("== 0.退出系统 ==\n");
printf("== ==\n");
printf("==========================\n");
}
void menu2(void)
{
printf("==========================\n");
printf("=========顾客你好======== \n");
printf("== ==\n");
printf("== 1.加入排队 ==\n");
printf("== 2.是否有人等餐 ==\n");
printf("== 0.退出系统 ==\n");
printf("== ==\n");
printf("==========================\n");
}
bool InitQuene(SqList& q)
{
q = (SqList)malloc(sizeof(LinkQuene));
//malloc有一定几率申请空间失败,此时继续申请,直到申请成功
while (!q) {
q = (SqList)malloc(sizeof(Quene));
}
q->front = q->rear = NULL; //此时队列无元素(两个下标之间差的绝对值为0)
return true;
}
bool DestroyQuene(SqList& q)
{
List p; //工作指针
while (q->front != q->rear) { //当队列中的结点大于一个时循环
p = q->front; //工作指针指向队首结点
q->front = q->front->next; //队首结点后移
free(p); //释放掉工作指针指向的结点
}
p = q->front;
free(p); //释放掉最后一个结点
free(q); //释放掉链队结点
return true;
}
bool QueneEmpty(SqList& q)
{
return (q->front == NULL); //当队列为空时返回“真”,否则返回“假”
}
bool enQuene(SqList& q, Elemtype e)
{
List p = (List)malloc(sizeof(Quene));
//malloc有一定几率申请空间失败,此时继续申请,直到申请成功
while (!p) {
p = (List)malloc(sizeof(Quene));
}
p->data = e;
p->next = NULL;
if (q->rear == NULL)
q->front = q->rear = p; //当链队为空时,新结点既是头结点又是尾结点
else {
q->rear->next = p; //将新结点接到队尾
q->rear = p; //队尾移动
}
return true;
}
bool deQuene(SqList& q, Elemtype& e)
{
if (q->front == NULL) //当队列为空时无法出队,返回“假”
return false;
List p = q->front; //工作指针指向队首
if (q->front == q->rear) //当链队中只有一个结点时
q->front = q->rear = NULL;
else //当链队中有一个以上的结点时
q->front = q->front->next;
e = p->data;
free(p);
return true;
}