银行取号机
(1)设计思路:每个银行都有若干个柜台,初始时建一个队列数组,保存各个柜台的工作信息。
使用对象:银行职员处理业务,客户办理业务。
客户取号办理业务,应该选择排队人数最少的柜台进行排队。每个客户看作一个结点,每个结点中包括该客户的编号和指向下一个结点的指针。为每个柜台构造一个队列,存放队列的头尾指针和队列的人数。
(2)实现的功能:
1.客户的取号
2.删除号码
3.查看当前排队信息
4.银行管理柜台(仅限银行职员使用)
*使用时需要输入密码
*进入后可以选择柜台叫号、关闭柜台、查看当前柜台工作信息
(3)结构体定义
typedef struct person {int num; //客户拿到的号码struct person *next;}person, *personPtr;typedef struct {personPtr front;personPtr rear;int count; //队列的人数}LinkQueue;int queueNum; //当前队列的数量LinkQueue s[COUNTERNUM+1];
(4)宏定义及函数
#define COUNTERNUM 5#define OVERFLOW -2#include<stdio.h>#include<malloc.h>#include<stdlib.h>#include<string.h>void InitQueue()//构造空队列void DestroyQueue(int x) //销毁队列void printQueue(int x) //打印客户排队信息void EnQueue() //插入元素为新的队尾元素void call(int n) //n号柜台叫号,即客户出队void delnum(int cnum, int num) //客户删除自己的号码void select()//查询当前柜台信息void menu()//菜单界面void login()//银行职员登陆void endwork()//结束柜台工作void startwork()//启动柜台叫号void printcounter()//打印当前柜台工作信息void bankmenu()//银行操作柜台菜单界面void bank()//银行工作
(5)功能实现
功能选择界面
取号
删除自己的号码
查看当前排队信息
柜台操作
查看柜台工作信息
柜台叫号
柜台结束工作
源码
#pragma warning(disable:4996)
#define COUNTERNUM 5
#define OVERFLOW -2
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>typedef struct person {int num; //客户拿到的号码struct person *next;
}person, *personPtr;typedef struct {personPtr front;personPtr rear;int count; //队列的人数
}LinkQueue;int queueNum; //当前队列的数量
LinkQueue s[COUNTERNUM+1];
//int workFlag[COUNTERNUM + 1];void InitQueue() {//构造空队列LinkQueue q;q.front = q.rear = (personPtr)malloc(sizeof(person));if (!q.front)exit(OVERFLOW);q.front->next = NULL;s[queueNum + 1] = q; //队列从1开始编号s[queueNum + 1].count = 0;queueNum++;
}
void DestroyQueue(int x) {//销毁队列LinkQueue Q = s[x];while (Q.front) {Q.rear = Q.front->next;free(Q.front);Q.front = Q.rear;}queueNum--;
}void printQueue(int x) {//打印客户排队信息printf("您已在%d号柜台排队\n", x);printf("您的号码为%d,请耐心等待\n\n", s[x].count);
}void EnQueue() {//插入元素为新的队尾元素personPtr p = (personPtr)malloc(sizeof(person));if (!p)exit(OVERFLOW);if (queueNum < COUNTERNUM) { //如果此时有空余的柜台则创建一个新的队列InitQueue(); //构造了一个空队列p->num = 1;//P为队列的第一个人,编号为1s[queueNum].rear->next = p;s[queueNum].rear = p;p->next = NULL;s[queueNum].count++;int x = queueNum;printQueue(x);}else { //柜台已满,在所有柜台中查找人数最少的进行插入int min = s[1].count;int x=1;for (int i = 2; i <= COUNTERNUM; i++) {if (s[i].count < min){min = s[i].count;x = i;}//if}//for//找到人数最少的队列之后进行插入s[x].rear->next = p;s[x].rear = p;p->next = NULL;s[x].count++;p->num = s[x].count;printQueue(x);}//else
}void call(int n) {//n号柜台叫号,即客户出队LinkQueue Q = s[n];if (Q.front == Q.rear) {printf("%d号柜台叫号完毕\n", n);return;}if (Q.count==1) { Q.rear = Q.front; s[n].count = 0;printf("请%d号柜台%d号客户办理业务\n", n,1);return;}//队列中只有一个人personPtr p = Q.front->next;while(p) {printf("请%d号柜台%d号客户办理业务\n", n, p->num);p = p->next;s[n].count--;}printf("%d号柜台叫号结束\n\n",n);
}void delnum(int cnum, int num) {//客户删除自己的号码if (cnum > queueNum) {printf("输入有误,该柜台没有工作\n");return;}LinkQueue Q = s[cnum];personPtr p ;p = s[cnum].front->next;personPtr pre;pre = s[cnum].front;if (num > Q.count) {printf("输入有误,您的号码不在此柜台队列中\n");return;}if(Q.count == 1) {if (p->num != num) {printf("输入有误,您的号码不在此柜台队列中\n");return;}s[cnum].count = 0;s[cnum].front= s[cnum].rear;s[cnum].rear->next = NULL;printf("删除成功!\n");}else {while (p->next != NULL) {if (p->num == num) {pre->next = p->next;free(p);p = NULL;break;}else {p = p->next;pre = pre->next;}}if (p != NULL) {if (p->num == num) {pre->next = p->next;free(p);p = NULL;}}s[cnum].count--;printf("删除成功!\n");}}void select() {if (queueNum == 0) {printf("当前无排队队列\n");}else {printf("当前排队的队列有:\n");for (int i = 1; i <= COUNTERNUM; i++) {if(s[i].front!= s[i].rear)printf("队列%d,人数%d\n", i, s[i].count);}}
}
void menu() {printf("\n\n欢迎使用银行取号机\n");printf("1.取号\n");printf("2.删除号码\n");printf("3.查看当前排队信息\n");printf("4.柜台工作安排(仅限银行职员使用)\n\n\n");
}
void login() {char psword[20] = "0000"; //设置原始密码为0000char inpsw[20];int q = 0;printf("请输入登录密码************\n");scanf("%s", inpsw);if (strcmp(psword, inpsw) != 0) { //验证密码是否正确q = 1;printf("密码错误,请重新输入\n");while (q = 1) {scanf("%s", inpsw);if (strcmp(psword, inpsw) == 0)break;else printf("密码错误,请重新输入\n");}}printf("密码正确,欢迎使用银行取号机\n\n");//若密码正确则进入学生信息系统}void endwork() {printf("请输入要结束工作的柜台编号\n");int a;scanf("%d", &a);DestroyQueue(a);printf("%d号柜台开始休息\n\n",a);
}
void startwork() {printf("请输入要开始叫号的柜台编号\n");int cnum;scanf("%d", &cnum);printf("%d号柜台开始叫号,请在%d号柜台排队等候的客户注意\n\n\n", cnum, cnum);call(cnum);
}
void printcounter() {if (queueNum == 0)printf("当前无柜台在工作\n");else {printf("当前工作的柜台:\n");for (int i = 1; i <= COUNTERNUM; i++) {if (s[i].front != s[i].rear)printf("%d号\n", i);}}
}
void bankmenu() {while (1) {printf("请选择你要进行的操作\n");printf("1.柜台开始叫号\n");printf("2.柜台结束工作\n");printf("3.查看当前柜台工作情况\n");printf("4.返回\n");int choice;scanf("%d", &choice);switch (choice) {case 1: startwork(); break;case 2: endwork(); break;case 3:printcounter(); break;default:return;}}
}
void bank() {login();bankmenu();
}
int main() {while (1) {menu();int choice;scanf("%d", &choice);switch (choice){case 1:EnQueue(); break;case 2:printf("请输入柜台号和您的排队号码\n");int cnum, num;scanf("%d%d", &cnum, &num);delnum(cnum, num);break;case 3:select();break;case 4:bank();break;default:printf("输入有误!\n");break;}}
}