C:从双链接队列中删除前端节点

C:从双链接队列中删除前端节点,c,linked-list,C,Linked List,我在概念化如何从双链接队列中删除前端节点时遇到了一些问题。我添加了一些其他的代码片段,这些代码应该可以为您提供一些我正在使用的内容的背景信息。我已经为remove_queue函数准备了一些东西,但是我不确定它是否正确或者如何完成它 struct Queue { int size; struct QueueNode *dummy_head_node_ptr; }; struct QueueNode { int value; struct QueueNode *pr

我在概念化如何从双链接队列中删除前端节点时遇到了一些问题。我添加了一些其他的代码片段,这些代码应该可以为您提供一些我正在使用的内容的背景信息。我已经为remove_queue函数准备了一些东西,但是我不确定它是否正确或者如何完成它

struct Queue {
    int size;
    struct QueueNode *dummy_head_node_ptr;
};

struct QueueNode {
    int value;
    struct QueueNode *prev_node_ptr;
    struct QueueNode *next_node_ptr;
};

void init_queue(struct Queue *queue_ptr) {
    struct QueueNode *node_ptr;

    // Create a dummy node and make it to point to itself
    node_ptr = (struct QueueNode *)malloc(sizeof(struct QueueNode));
    node_ptr->prev_node_ptr = node_ptr;
    node_ptr->next_node_ptr = node_ptr;

    // Set the queue struct to have a size of zero and
    // point to the dummy node
    queue_ptr->size = 0;
    queue_ptr->dummy_head_node_ptr = node_ptr;
}
void insert_queue(int value, struct Queue *queue_ptr)
{
    struct QueueNode *new_node_ptr;
    new_node_ptr = (struct QueueNode *)malloc(sizeof(struct QueueNode));

    new_node_ptr->next_node_ptr = queue_ptr->dummy_head_node_ptr;
    new_node_ptr->prev_node_ptr = queue_ptr->dummy_head_node_ptr->prev_node_ptr;
    queue_ptr->dummy_head_node_ptr->prev_node_ptr->next_node_ptr = new_node_ptr;
    queue_ptr->dummy_head_node_ptr->prev_node_ptr = new_node_ptr;

    new_node_ptr->value = value;
    queue_ptr->size++;
}
int remove_queue(struct Queue *queue_ptr)
{
    assert(queue_ptr->size > 0);

    queue_ptr->dummy_head_node_ptr->prev_node_ptr->next_node_ptr = queue_ptr->dummy_head_node_ptr->prev_node_ptr;
    queue_ptr->dummy_head_node_ptr->prev_node_ptr = NULL;

    queue_ptr->size = queue_ptr->size - 1;
    return queue_ptr->dummy_head_node_ptr->next_node_ptr->value;    
}

你必须记住头部节点。将头节点的继任者替换为头节点。记住头节点和自由头节点的成员

int remove_queue(struct Queue *queue_ptr)
{
    assert(queue_ptr->size > 0);
    if ( size == 0 )
        return queue_ptr->dummy_head_node_ptr->value;

    struct QueueNode *firstNode = queue_ptr->dummy_head_node_ptr->nextNode;
    int value = firstNode->value;       // remember value of first node
    queue_ptr->size--;                  // decrement number of nodes

    struct QueueNode *nextNode  = firstNode->next_node_ptr;

    queue_ptr->dummy_head_node_ptr = nextNode;                // new head is successor of head node
    nextNode->prev_node_ptr = queue_ptr->dummy_head_node_ptr; // predecessor of new head node is queue_ptr->dummy_head_node_ptr
                                                              // if queue_ptr->size == 0 then nextNode == queue_ptr->dummy_head_node_ptr

    free( firstNode  );                                       // free first node
    return value;   
}

你必须记住头部节点。将头节点的继任者替换为头节点。记住头节点和自由头节点的成员

int remove_queue(struct Queue *queue_ptr)
{
    assert(queue_ptr->size > 0);
    if ( size == 0 )
        return queue_ptr->dummy_head_node_ptr->value;

    struct QueueNode *firstNode = queue_ptr->dummy_head_node_ptr->nextNode;
    int value = firstNode->value;       // remember value of first node
    queue_ptr->size--;                  // decrement number of nodes

    struct QueueNode *nextNode  = firstNode->next_node_ptr;

    queue_ptr->dummy_head_node_ptr = nextNode;                // new head is successor of head node
    nextNode->prev_node_ptr = queue_ptr->dummy_head_node_ptr; // predecessor of new head node is queue_ptr->dummy_head_node_ptr
                                                              // if queue_ptr->size == 0 then nextNode == queue_ptr->dummy_head_node_ptr

    free( firstNode  );                                       // free first node
    return value;   
}
但是,内存泄漏是不好的做法,所以不要忘记释放头部节点

因此,将dummy_head_node_ptr->next_node_ptr保存到临时变量中。然后在最后释放它

但是,内存泄漏是不好的做法,所以不要忘记释放头部节点


因此,将dummy_head_node_ptr->next_node_ptr保存到临时变量中。然后在最后释放它。

如果您想了解代码在做什么(鉴于您甚至不确定代码是否正确,这似乎是必要的),我建议您将数据绘制在纸上——框表示节点,线/箭头表示指针。然后在心里逐步完成代码,并根据需要调整图形。如果你有一个白板,那可能会更容易。我知道我的代码做什么,并且一直在使用视觉效果。正是删除队列给我带来了麻烦。除非
remove\u queue()
不是您的代码的一部分,否则我的声明仍然有效。在这个函数上使用相同的视觉效果是无法替代的,这样您就可以真正理解它。除非你能描述一个具体的问题(“我不知道它是否有效”不是一个具体的问题),否则堆栈溢出真的没有什么可以帮助的。我一直在这么做,哈哈。所以在你的视觉中删除你想从队列中移除的项。哪些指针悬而未决?如果你想了解你的代码在做什么(这似乎是必要的,因为你甚至不确定它是否正确),我建议你把数据画在纸上——框代表节点,线/箭头代表指针。然后在心里逐步完成代码,并根据需要调整图形。如果你有一个白板,那可能会更容易。我知道我的代码做什么,并且一直在使用视觉效果。正是删除队列给我带来了麻烦。除非
remove\u queue()
不是您的代码的一部分,否则我的声明仍然有效。在这个函数上使用相同的视觉效果是无法替代的,这样您就可以真正理解它。除非你能描述一个具体的问题(“我不知道它是否有效”不是一个具体的问题),否则堆栈溢出真的没有什么可以帮助的。我一直在这么做,哈哈。所以在你的视觉中删除你想从队列中移除的项。哪些指针悬空了?他有个假脑袋。因此,据我所知,不应删除假人头部。他的代码将被完全重写。所以你的答案无关紧要。这让我朝着正确的方向前进。谢谢,@rabbi76。在执行任何操作之前,必须首先声明
queue_ptr
不是
NULL
。这是因为
queue\u ptr->size
queue\u ptr==NULL
的情况下会给您
分段错误
!他有一个假脑袋。因此,据我所知,不应删除假人头部。他的代码将被完全重写。所以你的答案无关紧要。这让我朝着正确的方向前进。谢谢,@rabbi76。在执行任何操作之前,必须首先声明
queue_ptr
不是
NULL
。这是因为
queue\u ptr->size
queue\u ptr==NULL
的情况下会给您
分段错误
dummy_head_node_ptr->next_node_ptr = dummy_head_node_ptr->next_node_ptr->next_node_ptr;