【问题标题】:How to dequeue en element from my custom queue如何从我的自定义队列中取出元素
【发布时间】:2014-04-26 14:33:07
【问题描述】:

作为练习,我正在尝试创建一个基本队列。我的deQueue 方法有问题。

#include<stdio.h>

typedef int Task;
typedef struct QueueNode_ QueueNode;
typedef struct TQueue_ TQueue;

struct QueueNode_ {
    QueueNode* next;
    Task task;
};

struct TQueue_ {
    QueueNode* first;
    QueueNode* last;
};

TQueue* initializeQueue(){
    TQueue* queue = NULL;
    queue = malloc(sizeof(TQueue));
    queue->first = NULL;
    queue->last = NULL;
    return queue;
}

void enQueue(TQueue* q, Task t){
    if(q->first == NULL){
       q->first = malloc(sizeof(QueueNode));
       q->first->task = t;
       q->first->next = NULL;
       q->last = q->first;
    } else {
        QueueNode* node = malloc(sizeof(QueueNode));
        node->next = q->last;
        node->task = t;
        q->last = node;
    }
}

void printQueue(TQueue* q){
    QueueNode* node = q->last;
    printf("LAST->");
    while(node != NULL){
        printf("%d->", node->task);
        node = node->next;
    }
    printf("FIRST\n");
}

QueueNode* deQueue(TQueue* q){
    QueueNode* temp = q->first;
    QueueNode* newFirst = q->last;
    q->first = NULL;
    while(newFirst != NULL){
        newFirst = newFirst->next;
    }
    q->first = newFirst;
    return temp;
}

int main(){
    TQueue* queue = initializeQueue();
    enQueue(queue, 1);
    enQueue(queue, 2);
    printQueue(queue);
    QueueNode* node = deQueue(queue);
    printf("%d\n", node->task);
    printQueue(queue);
    return 0;
}

我希望我的 deQueue 方法能够移除队列的头部。但显然情况并非如此。

这是输出:

LAST->2->1->FIRST
1
LAST->2->1->FIRST

我怀疑我的deQueue 方法不会用第二个元素替换队列的头部,但我虽然是用q-&gt;first = newFirst; 做的,所以我有点卡住了。

如果不清楚,我希望它会打印出来:

LAST->2->1->FIRST
1
LAST->2->FIRST

【问题讨论】:

    标签: c pointers queue


    【解决方案1】:

    你可以这样做:

    QueueNode* deQueue(TQueue* q){
        QueueNode *tmp = q->last;
    
        while(tmp->next != q->first) {
            tmp = tmp->next;
        }
        // new first is now the old second element
        q->first = tmp;
    
        // new firsts' next still points at 
        // old first so we free that memory here
        free(q->first->next);
        q->first->next = NULL;
    
        return tmp;
    }
    

    别忘了释放你的记忆。

    你可以在这里测试它:http://www.compileonline.com/compile_c_online.php

    【讨论】:

    • 是的,这就行了!你知道为什么我当前的实现不起作用吗?
    • while-条件似乎是问题所在。您一直在迭代直到列表的末尾,但您应该在此之前停止一个元素。
    • 是的,但是通过在此之前执行q-&gt;first = NULL;,我希望它之前会停止一个元素,这就是我不明白的原因..
    • 你应该仔细看看你的代码。你正在设置例如temp = q-&gt;first 但是你设置了q-&gt;first = NULL 这使得tempNULL 这意味着你总是在这里返回NULL。除此之外,你应该小心不要丢失最后一个指针来释放你正在出队的那个节点的内存(愚蠢的词^^)。而且我认为它没有达到您的预期,因为newFirst-&gt;next 从未更改过。您正在设置q-&gt;first = NULL,但节点本身仍然获得有效的next 指针。
    • 好吧,我明白了,但你是说我总是返回 NULL 对吧?那么为什么在执行printf("%d\n", node-&gt;task); 时它会在我的输出中打印 1?如果它返回null,它应该在这里停止程序吗? (printf("%d\n", node==NULL); 输出 0)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-02
    • 2018-08-11
    • 1970-01-01
    • 2021-11-26
    • 2012-03-19
    • 2021-07-20
    • 1970-01-01
    相关资源
    最近更新 更多