按客户类型实现队列进出:修改LIST/OUT命令及解决实现异常
Hey there! Let's work through your queue problem together. First, let's fix the garbled text issue in your current dual-queue setup, then I'll show you a solid alternative using a single queue with priority handling.
Fixing Your Dual-Queue Code
First, let's diagnose why your current code is showing messed-up card numbers and customer types:
- Wrong data type for
CardNum: You declaredCardNumas anint, but tried to usestrcpy(a string function) on it. Card numbers often have leading zeros or are too long for integers, so it should be a character array instead. - Mistaken
strcpycalls: In yourEnqueuefunction, you copied both the card number and customer type totemp->CardNum, leavingtemp->CustomerTypeuninitialized (hence the garbled text). - Uninitialized queues: You never set
q1.front,q1.rear,q2.front,q2.reartoNULLat the start, which can cause undefined behavior.
Here's the corrected dual-queue code that meets your requirements:
#include <stdio.h> #include <malloc.h> #include<string.h> // Global counter for sequential record numbers int global_record = 1; typedef struct Node { int record; char CardNum[20]; // Changed to char array for valid card storage char CustomerType[20]; struct Node* next; } Node; typedef struct queue { Node* front; Node* rear; } Queue; Queue q1, q2; // q1 = VIP queue, q2 = Ordinary queue void Enqueue(Queue *q, char *card, char *type); void List(); void Out(); int main() { char command[10]; char card[20], client[20]; // Initialize queues to empty state q1.front = q1.rear = NULL; q2.front = q2.rear = NULL; while(1) { scanf("%s", command); if(strcmp(command,"IN") == 0) { printf("IN: "); scanf("%s %s", card, client); if(strcmp(client,"VIP") == 0) { Enqueue(&q1, card, client); } else if(strcmp(client,"Ordinary") == 0) { Enqueue(&q2, card, client); } } else if(strcmp(command,"LIST") == 0) { printf("LIST:\n"); List(); } else if(strcmp(command,"OUT") == 0) { printf("OUT:\n"); Out(); } else if(strcmp(command,"QUIT") ==0) { printf("GOOD BYE!\n"); break; } } return 0; } void Enqueue(Queue *q, char *card, char *type) { Node* temp = (Node*)malloc(sizeof(Node)); if (!temp) { printf("Memory allocation failed!\n"); return; } temp->record = global_record++; strcpy(temp->CardNum, card); strcpy(temp->CustomerType, type); temp->next = NULL; if(q->front == NULL && q->rear == NULL) { q->front = q->rear = temp; } else { q->rear->next = temp; q->rear = temp; } printf("Enqueued: %d %s %s\n", temp->record, temp->CardNum, temp->CustomerType); } void List() { // Print all VIP customers first (in enqueue order) Node *temp = q1.front; while(temp != NULL) { printf("%d %s %s\n", temp->record, temp->CardNum, temp->CustomerType); temp = temp->next; } // Then print all Ordinary customers temp = q2.front; while(temp != NULL) { printf("%d %s %s\n", temp->record, temp->CardNum, temp->CustomerType); temp = temp->next; } } void Out() { // Prioritize VIP queue for dequeue if (q1.front != NULL) { Node *temp = q1.front; printf("%d %s %s\n", temp->record, temp->CardNum, temp->CustomerType); q1.front = q1.front->next; // Update rear if queue becomes empty if (q1.front == NULL) { q1.rear = NULL; } free(temp); } else if (q2.front != NULL) { Node *temp = q2.front; printf("%d %s %s\n", temp->record, temp->CardNum, temp->CustomerType); q2.front = q2.front->next; if (q2.front == NULL) { q2.rear = NULL; } free(temp); } else { printf("Queue is empty!\n"); } }
Alternative: Single Queue with Priority Handling
If you prefer not to use two separate queues, you can use a single queue where each node tracks its customer type. Here's how to implement the required behavior:
#include <stdio.h> #include <malloc.h> #include<string.h> int global_record = 1; typedef struct Node { int record; char CardNum[20]; char CustomerType[20]; struct Node* next; } Node; typedef struct queue { Node* front; Node* rear; } Queue; Queue q; void Enqueue(char *card, char *type); void List(); void Out(); int main() { char command[10]; char card[20], client[20]; q.front = q.rear = NULL; while(1) { scanf("%s", command); if(strcmp(command,"IN") == 0) { printf("IN: "); scanf("%s %s", card, client); Enqueue(card, client); } else if(strcmp(command,"LIST") == 0) { printf("LIST:\n"); List(); } else if(strcmp(command,"OUT") == 0) { printf("OUT:\n"); Out(); } else if(strcmp(command,"QUIT") ==0) { printf("GOOD BYE!\n"); break; } } return 0; } void Enqueue(char *card, char *type) { Node* temp = (Node*)malloc(sizeof(Node)); if (!temp) { printf("Memory allocation failed!\n"); return; } temp->record = global_record++; strcpy(temp->CardNum, card); strcpy(temp->CustomerType, type); temp->next = NULL; if(q.front == NULL && q.rear == NULL) { q.front = q.rear = temp; } else { q.rear->next = temp; q.rear = temp; } printf("Enqueued: %d %s %s\n", temp->record, temp->CardNum, temp->CustomerType); } void List() { // First print all VIP customers (maintaining enqueue order) Node *temp = q.front; while(temp != NULL) { if (strcmp(temp->CustomerType, "VIP") == 0) { printf("%d %s %s\n", temp->record, temp->CardNum, temp->CustomerType); } temp = temp->next; } // Then print all Ordinary customers temp = q.front; while(temp != NULL) { if (strcmp(temp->CustomerType, "Ordinary") == 0) { printf("%d %s %s\n", temp->record, temp->CardNum, temp->CustomerType); } temp = temp->next; } } void Out() { if (q.front == NULL) { printf("Queue is empty!\n"); return; } // Dequeue front if it's VIP if (strcmp(q.front->CustomerType, "VIP") == 0) { Node *temp = q.front; printf("%d %s %s\n", temp->record, temp->CardNum, temp->CustomerType); q.front = q.front->next; if (q.front == NULL) q.rear = NULL; free(temp); return; } // Find and dequeue the first VIP in the queue Node *prev = q.front; Node *curr = q.front->next; while (curr != NULL) { if (strcmp(curr->CustomerType, "VIP") == 0) { printf("%d %s %s\n", curr->record, curr->CardNum, curr->CustomerType); prev->next = curr->next; if (curr == q.rear) q.rear = prev; free(curr); return; } prev = curr; curr = curr->next; } // No VIPs left, dequeue front ordinary node Node *temp = q.front; printf("%d %s %s\n", temp->record, temp->CardNum, temp->CustomerType); q.front = q.front->next; if (q.front == NULL) q.rear = NULL; free(temp); }
Key Notes for the Single Queue Approach
- LIST: Traverses the queue twice to separate VIP and ordinary entries, keeping their original enqueue order intact within each group.
- OUT: Checks for a VIP at the front first; if none exists, it searches for the first VIP in the queue to dequeue. Only when no VIPs are left does it dequeue an ordinary customer.
Both implementations fulfill your requirements:
LISToutputs VIP customers first (in ascending order of their queue entry), followed by ordinary customers.OUTalways prioritizes VIP customers for dequeuing.
内容的提问来源于stack exchange,提问作者Zuher Abud
相关产品推荐
相关产品推荐

