I designed a circular queue program which provides queue management system. Everything works fine, except that in some cases, I can't print the queue.
My code:
#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);
}
When q.front
is greater than q.rear
, case 3
(the printing) doesn't print anything.
For example after the inputs below I can't display queue elements:
- 4 times CUSTOMER ENTRY(insert)
- 2 times CUSTOMER EXIT(delete)
- 2 times CUSTOMER ENTRY(insert)
- and select Waiting Customers List ---> here is the problem: it doesn't display elements in the queue.
You can use the following inputs to apply those steps:
1
c1
1
c2
1
c3
1
c4
2
2
1
c5
1
c6
3
4
How can I display the queue, even when q.front
is greater than q.rear
?
CodePudding user response:
Following your suggestion, let's see what happens when we insert 4 customers, then remove 2, then insert 2 more:
Initially:
rear = 4
front = 4
queue:
---------- ---------- ---------- ---------- ----------
| | | | | |
---------- ---------- ---------- ---------- ----------
After 4 inserts:
rear = 3
front = 4
queue:
---------- ---------- ---------- ---------- ----------
| "c1" | "c2" | "c3" | "c4" | |
---------- ---------- ---------- ---------- ----------
After 2 deletes:
rear = 3
front = 1
queue:
---------- ---------- ---------- ---------- ----------
| | | "c3" | "c4" | |
---------- ---------- ---------- ---------- ----------
After 2 more inserts:
rear = 0
front = 1
queue:
---------- ---------- ---------- ---------- ----------
| "c6" | | "c3" | "c4" | "c5" |
---------- ---------- ---------- ---------- ----------
To print this queue, you wrote this piece of code (we are in the else
of the case 3
since q.front
is not CAPACITY-1
):
order=1;
for(int i=q.front 1;i<=q.rear;i ) {
printf("[%d]-%s\n",order,q.items[i]);
order ;
}
i
is initialized at q.front 1 = 2
. The looping condition is i<=q.rear
. Since q.rear
is 0, this means i<=0
. This is already false before the first iteration since 2<=0
is false. Thus, nothing gets printed.
Informally, the way to print the queue is:
- print
c3
(index =q.front 1
) - print
c4
(index =q.front 2
) - print
c5
(index =q.front 3
) - print
c6
(index =(q.front 4) % CAPACITY
)
See what I did for c6
? I wrapped around to the beginning of the queue by doing % CAPACITY
. In fact, I could have added this % CAPACITY
to all the other cases, it just wouldn't have changed anything since q.front 1
/q.front 2
/q.front 3
are less than CAPACITY
.
In your code, you thought about wrapping around, but only when q.front
is CAPACITY-1
. Instead, you should always consider wrapping around. To do so, you can write the case 3
as follows (this is simply the algorithm corresponding to the informal steps I wrote above):
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;
The idea is to start from q.front
and continue looping until i
is q.rear
. However, while looping, we wrap around by doing i = (i 1) % CAPACITY
instead of i
.
Note how q.front==CAPACITY-1
is not a special case anymore: this loop will wrap around, regardless the value of q.front
.