如何显示整个队列结构
How to display an entire queue struct
我设计了一个提供队列管理系统的循环队列程序。一切正常,除了在某些情况下,我无法打印队列。
我的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CAPACITY 5
#define MAX_STRING_SIZE 40
#define TRUE 1
#define FALSE 0
struct queue
{
char items[CAPACITY][MAX_STRING_SIZE];
int front,rear ;
};
void cqinsert(struct queue * , char name[]);
void cqdelete(struct queue *);
int empty(struct queue *);
int main(void)
{
int order;
char name[MAX_STRING_SIZE];
int menu;
char operation;
int x;
struct queue q;
q.front = q.rear = CAPACITY - 1;
do{
printf(">>Please enter an operation number from the given list:\n");
printf("[1]-Customer Entry\n[2]-Customer Exit\n[3]-Waiting Customers List\n[4]-Exit\n");
scanf("%d",&menu);
switch(menu) {
case 1: printf("Enter customer name: ");
scanf("%s",&name);
cqinsert(&q,name);
break;
case 2: cqdelete(&q);
break;
case 3: if(q.front==CAPACITY-1) {
order = 1;
for(int i=0;i<=q.rear;i++) {
printf("[%d]-%s\n",order,q.items[i]);
order++;
}
break;
}
else {
order=1;
for(int i=q.front+1;i<=q.rear;i++) {
printf("[%d]-%s\n",order,q.items[i]);
order++;
}
break;
}
}
}while(menu!=4);
system("pause");
return 0;
}
int empty(struct queue *pq)
{
return((pq->front == pq->rear) ? TRUE : FALSE);
}
void cqdelete(struct queue *pq)
{
if (empty(pq)) {
printf("Queue is empty !");
exit(1);
}
if (pq->front == CAPACITY - 1)
pq->front = 0;
else
(pq->front)++;
printf("\n -----> %s is deleted from the queue. \n\n",pq->items[pq->front]);
}
void cqinsert(struct queue *pq , char name[])
{
printf("\n -----> %s is inserted to queue. \n\n",name);
if (pq->rear == CAPACITY - 1)
pq->rear = 0;
else
(pq->rear)++;
if (pq->rear == pq->front) {
printf("Queue is full !");
exit(1);
}
strcpy(pq->items[pq->rear],name);
}
当q.front
大于q.rear
时,case 3
(打印)不打印任何东西。
例如在下面的输入后我无法显示队列元素:
- 4 次客户输入(插入)
- 2 次客户退出(删除)
- 2 次客户输入(插入)
- 和select 等待客户列表 ---> 问题在于:它不显示队列中的元素。
您可以使用以下输入来应用这些步骤:
1
c1
1
c2
1
c3
1
c4
2
2
1
c5
1
c6
3
4
如何显示队列,即使 q.front
大于 q.rear
?
按照你的建议,让我们看看当我们插入 4 个客户,然后删除 2 个,然后再插入 2 个时会发生什么:
最初:
rear = 4
front = 4
queue:
+----------+----------+----------+----------+----------+
| | | | | |
+----------+----------+----------+----------+----------+
4次插入后:
rear = 3
front = 4
queue:
+----------+----------+----------+----------+----------+
| "c1" | "c2" | "c3" | "c4" | |
+----------+----------+----------+----------+----------+
2次删除后:
rear = 3
front = 1
queue:
+----------+----------+----------+----------+----------+
| | | "c3" | "c4" | |
+----------+----------+----------+----------+----------+
再插入 2 次后:
rear = 0
front = 1
queue:
+----------+----------+----------+----------+----------+
| "c6" | | "c3" | "c4" | "c5" |
+----------+----------+----------+----------+----------+
为了打印这个队列,你写了这段代码(我们在 case 3
的 else
因为 q.front
不是 CAPACITY-1
):
order=1;
for(int i=q.front+1;i<=q.rear;i++) {
printf("[%d]-%s\n",order,q.items[i]);
order++;
}
i
在 q.front+1 = 2
初始化。循环条件为i<=q.rear
。由于 q.rear
为 0,这意味着 i<=0
。由于 2<=0
为假,因此在第一次迭代之前这已经是假的。因此,不会打印任何内容。
非正式地,打印队列的方式是:
- 打印
c3
(索引=q.front + 1
)
- 打印
c4
(索引=q.front + 2
)
- 打印
c5
(索引=q.front + 3
)
- 打印
c6
(索引=(q.front + 4) % CAPACITY
)
看看我为 c6
做了什么?我通过 % CAPACITY
绕到队列的开头。事实上,我可以将这个 % CAPACITY
添加到所有其他情况,它不会改变任何东西,因为 q.front+1
/q.front+2
/q.front+3
小于 CAPACITY
.
在您的代码中,您考虑过回绕,但仅当 q.front
为 CAPACITY-1
时才考虑。相反,您应该 始终 考虑环绕。为此,您可以将 case 3
编写如下(这只是对应于我上面编写的非正式步骤的算法):
case 3:
for (int i = q.front; i != q.rear; i = (i+1) % CAPACITY) {
int order = (i+1-q.front+CAPACITY) % CAPACITY; // (... + CAPACITY) % CAPACITY ensures a positive number
printf("[%d]-%s\n", order, q.items[(i+1) % CAPACITY]);
}
break;
思路是从q.front
开始,一直循环直到i
为q.rear
。但是,在循环时,我们通过 i = (i+1) % CAPACITY
而不是 i++
.
来回绕
请注意 q.front==CAPACITY-1
不再是特例:无论 q.front
的值如何,此循环都会回绕。
我设计了一个提供队列管理系统的循环队列程序。一切正常,除了在某些情况下,我无法打印队列。
我的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CAPACITY 5
#define MAX_STRING_SIZE 40
#define TRUE 1
#define FALSE 0
struct queue
{
char items[CAPACITY][MAX_STRING_SIZE];
int front,rear ;
};
void cqinsert(struct queue * , char name[]);
void cqdelete(struct queue *);
int empty(struct queue *);
int main(void)
{
int order;
char name[MAX_STRING_SIZE];
int menu;
char operation;
int x;
struct queue q;
q.front = q.rear = CAPACITY - 1;
do{
printf(">>Please enter an operation number from the given list:\n");
printf("[1]-Customer Entry\n[2]-Customer Exit\n[3]-Waiting Customers List\n[4]-Exit\n");
scanf("%d",&menu);
switch(menu) {
case 1: printf("Enter customer name: ");
scanf("%s",&name);
cqinsert(&q,name);
break;
case 2: cqdelete(&q);
break;
case 3: if(q.front==CAPACITY-1) {
order = 1;
for(int i=0;i<=q.rear;i++) {
printf("[%d]-%s\n",order,q.items[i]);
order++;
}
break;
}
else {
order=1;
for(int i=q.front+1;i<=q.rear;i++) {
printf("[%d]-%s\n",order,q.items[i]);
order++;
}
break;
}
}
}while(menu!=4);
system("pause");
return 0;
}
int empty(struct queue *pq)
{
return((pq->front == pq->rear) ? TRUE : FALSE);
}
void cqdelete(struct queue *pq)
{
if (empty(pq)) {
printf("Queue is empty !");
exit(1);
}
if (pq->front == CAPACITY - 1)
pq->front = 0;
else
(pq->front)++;
printf("\n -----> %s is deleted from the queue. \n\n",pq->items[pq->front]);
}
void cqinsert(struct queue *pq , char name[])
{
printf("\n -----> %s is inserted to queue. \n\n",name);
if (pq->rear == CAPACITY - 1)
pq->rear = 0;
else
(pq->rear)++;
if (pq->rear == pq->front) {
printf("Queue is full !");
exit(1);
}
strcpy(pq->items[pq->rear],name);
}
当q.front
大于q.rear
时,case 3
(打印)不打印任何东西。
例如在下面的输入后我无法显示队列元素:
- 4 次客户输入(插入)
- 2 次客户退出(删除)
- 2 次客户输入(插入)
- 和select 等待客户列表 ---> 问题在于:它不显示队列中的元素。
您可以使用以下输入来应用这些步骤:
1
c1
1
c2
1
c3
1
c4
2
2
1
c5
1
c6
3
4
如何显示队列,即使 q.front
大于 q.rear
?
按照你的建议,让我们看看当我们插入 4 个客户,然后删除 2 个,然后再插入 2 个时会发生什么:
最初:
rear = 4
front = 4
queue:
+----------+----------+----------+----------+----------+
| | | | | |
+----------+----------+----------+----------+----------+
4次插入后:
rear = 3
front = 4
queue:
+----------+----------+----------+----------+----------+
| "c1" | "c2" | "c3" | "c4" | |
+----------+----------+----------+----------+----------+
2次删除后:
rear = 3
front = 1
queue:
+----------+----------+----------+----------+----------+
| | | "c3" | "c4" | |
+----------+----------+----------+----------+----------+
再插入 2 次后:
rear = 0
front = 1
queue:
+----------+----------+----------+----------+----------+
| "c6" | | "c3" | "c4" | "c5" |
+----------+----------+----------+----------+----------+
为了打印这个队列,你写了这段代码(我们在 case 3
的 else
因为 q.front
不是 CAPACITY-1
):
order=1;
for(int i=q.front+1;i<=q.rear;i++) {
printf("[%d]-%s\n",order,q.items[i]);
order++;
}
i
在 q.front+1 = 2
初始化。循环条件为i<=q.rear
。由于 q.rear
为 0,这意味着 i<=0
。由于 2<=0
为假,因此在第一次迭代之前这已经是假的。因此,不会打印任何内容。
非正式地,打印队列的方式是:
- 打印
c3
(索引=q.front + 1
) - 打印
c4
(索引=q.front + 2
) - 打印
c5
(索引=q.front + 3
) - 打印
c6
(索引=(q.front + 4) % CAPACITY
)
看看我为 c6
做了什么?我通过 % CAPACITY
绕到队列的开头。事实上,我可以将这个 % CAPACITY
添加到所有其他情况,它不会改变任何东西,因为 q.front+1
/q.front+2
/q.front+3
小于 CAPACITY
.
在您的代码中,您考虑过回绕,但仅当 q.front
为 CAPACITY-1
时才考虑。相反,您应该 始终 考虑环绕。为此,您可以将 case 3
编写如下(这只是对应于我上面编写的非正式步骤的算法):
case 3:
for (int i = q.front; i != q.rear; i = (i+1) % CAPACITY) {
int order = (i+1-q.front+CAPACITY) % CAPACITY; // (... + CAPACITY) % CAPACITY ensures a positive number
printf("[%d]-%s\n", order, q.items[(i+1) % CAPACITY]);
}
break;
思路是从q.front
开始,一直循环直到i
为q.rear
。但是,在循环时,我们通过 i = (i+1) % CAPACITY
而不是 i++
.
请注意 q.front==CAPACITY-1
不再是特例:无论 q.front
的值如何,此循环都会回绕。