You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:00:24