如何显示整个队列结构

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(打印)不打印任何东西。

例如在下面的输入后我无法显示队列元素:

您可以使用以下输入来应用这些步骤:

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 3else 因为 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++;
}

iq.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.frontCAPACITY-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开始,一直循环直到iq.rear。但是,在循环时,我们通过 i = (i+1) % CAPACITY 而不是 i++.

来回绕

请注意 q.front==CAPACITY-1 不再是特例:无论 q.front 的值如何,此循环都会回绕。