C语言Queue遍历异常求助:移除元素后无法显示最后元素
队列遍历功能异常排查与修复
我用C语言实现了队列数据结构,需求是向队列添加若干3的倍数、打印队列内容并逐个移除元素。经检查元素存储位置正确,但遍历(Traverse)功能存在异常:移除元素3后,后续的移除操作中无法显示队列的最后一个元素。
错误原因定位
问题出在TraverseQ函数的循环条件上:
原代码中使用current != Queue.Count作为循环终止条件,这是逻辑错误——current是队列元素的索引位置,Count是队列内元素的总数,两者没有直接的等价关系。当队列的Front指针不为0时,这个条件会导致循环提前终止,遗漏最后一个元素。
修复方案
修改TraverseQ函数,改为根据Count值来控制遍历次数,确保遍历到队列中的每一个元素:
void TraverseQ(QueueType Queue) { int current, i; printf("Queue: "); if (!EmptyQ(Queue)) { current = Queue.Front; // 遍历Count次,确保所有元素都被访问 for (i = 0; i < Queue.Count; i++) { printf("%d ", Queue.Element[current]); current = (current + 1) % (QueueLimit - 1); } printf("\n"); printf("Front=%d Rear=%d Count=%d\n", Queue.Front, Queue.Rear, Queue.Count); } else printf("Empty Queue\n"); }
完整修复后的代码
/* * File name: a15f3.c ------------------ */ #include <stdio.h> #define QueueLimit 11 typedef int QueueElementType; typedef struct { int Front, Rear; int Count; QueueElementType Element[QueueLimit]; } QueueType; typedef enum { FALSE, TRUE } boolean; void CreateQ(QueueType* Queue); boolean EmptyQ(QueueType Queue); boolean FullQ(QueueType Queue); void RemoveQ(QueueType* Queue, QueueElementType* Item); void AddQ(QueueType* Queue, QueueElementType Item); void TraverseQ(QueueType Queue); int main() { //Variable declaration QueueType Q; QueueElementType Item; int i, num; CreateQ(&Q); for (i = 3; i <= 30; i += 3) AddQ(&Q, i); printf("(a)\n"); TraverseQ(Q); printf("(b)\n"); do { printf("Give a number:"); scanf("%d", &num); if ((num % 3) != 0) printf("Give a multiple of 3\n"); } while ((num % 3) != 0); AddQ(&Q, num); TraverseQ(Q); printf("(c)\n"); RemoveQ(&Q, &Item); TraverseQ(Q); printf("Removed item=%d\n", Item); printf("(d)\n"); for (i = 0; i < 2; i++) { do { printf("Give a number:"); scanf("%d", &num); if ((num % 3) != 0) printf("Give a multiple of 3\n"); } while ((num % 3) != 0); AddQ(&Q, num); TraverseQ(Q); } printf("(e)\n"); while(!EmptyQ(Q)) { RemoveQ(&Q, &Item); TraverseQ(Q); printf("Removed item=%d\n", Item); } return 0; } void CreateQ(QueueType* Queue) { Queue->Front = 0; Queue->Rear = 0; Queue->Count = 0; } boolean EmptyQ(QueueType Queue) { return (Queue.Count == 0); } boolean FullQ(QueueType Queue) { return (Queue.Count == (QueueLimit - 1)); } void RemoveQ(QueueType* Queue, QueueElementType* Item) { if (!EmptyQ(*Queue)) { *Item = Queue->Element[Queue->Front]; Queue->Front = (Queue->Front + 1) % (QueueLimit - 1); Queue->Count--; } else printf("Empty Queue\n"); } void AddQ(QueueType* Queue, QueueElementType Item) { if (!FullQ(*Queue)) { Queue->Element[Queue->Rear] = Item; Queue->Rear = (Queue->Rear + 1) % (QueueLimit - 1); Queue->Count++; } else printf("Full Queue\n"); } void TraverseQ(QueueType Queue) { int current, i; printf("Queue: "); if (!EmptyQ(Queue)) { current = Queue.Front; for (i = 0; i < Queue.Count; i++) { printf("%d ", Queue.Element[current]); current = (current + 1) % (QueueLimit - 1); } printf("\n"); printf("Front=%d Rear=%d Count=%d\n", Queue.Front, Queue.Rear, Queue.Count); } else printf("Empty Queue\n"); }
修复效果说明
修复后,遍历函数会严格按照队列内的元素数量(Count)来遍历所有元素,无论Front指针处于什么位置,都能完整输出队列中的全部内容,解决了移除元素后无法显示最后一个元素的问题。
内容的提问来源于stack exchange,提问作者Tolis Snr
相关产品推荐
相关产品推荐

