gpt4 book ai didi

c - 使用单链表更新队列 adt 中的尾指针时遇到问题

转载 作者:行者123 更新时间:2023-11-30 14:23:35 25 4
gpt4 key购买 nike

我正在尝试制作一个基于我已经制作的链接列表库的队列库。具体来说,在将新节点添加到链表后,我在更新队列结构中的尾指针时遇到问题。

链表结构:

struct listNode {
int nodeLength;
int nodeValue;
struct listNode *next;
};

typedef struct listNode node;

队列结构:

struct QueueRecord {
node *list;
node *front;
node *back;
int maxLen;
};
typedef struct QueueRecord queue;

这是我在队列库中的添加函数

void add(queue currentQueue, int data){
addTail(currentQueue.list, data, data+5);
currentQueue.back = currentQueue.back->next;

}

以及链表库中的addTail函数

void addTail (node *head, int value, int length) {
node *current = head;
node *newNode = (struct listNode *)malloc(sizeof(node));
newNode = initNode(value, length);

while (current->next != NULL)
current = current->next;

newNode->next = NULL;
current->next = newNode;
}

所以我的问题又是尾指针没有设置到列表中的最后一个节点。它与头指针保持在同一位置。我已经研究了几个小时,试图看看我是否错过了一些小东西,但我找不到它。如果需要更多代码或解释来理解我的问题,我可以提供。

如何创建队列:

queue createQueue(int maxLen){
queue newQueue;
newQueue.list = createList();
newQueue.front = newQueue.list;
newQueue.back = newQueue.list;
newQueue.maxLen = maxLen;
return newQueue;
}

node *createList (){
node *head = NULL;
head = (struct listNode *)malloc(sizeof(node));
head->next = NULL;
return head;
}

node *initNode (int value, int length){
node *newNode = NULL;
newNode = (struct listNode *)malloc(sizeof(node));
newNode->nodeValue = value;
newNode->nodeLength = length;
newNode->next = NULL;
return newNode;
}

最佳答案

void add(queue currentQueue, int data){

您将 queue 结构的副本传递给add,因此仅更改副本的成员。您需要将 queue* 传递给函数才能更改 queue 本身的成员。

void add(queue *currentQueue, int data){
if (currentQueue == NULL) {
exit(EXIT_FAILURE);
}
addTail(currentQueue->list, data, data+5);
currentQueue->back = currentQueue->back->next;
}

并将其调用为add(&your_queue);

在您的 addTail 函数中,您也应该检查 head 是否为 NULL

还有

node *newNode = (struct listNode *)malloc(sizeof(node));
newNode = initNode(value, length);

addTail中,你遇到了一个严重的问题。通过赋值 newNode = initNode(value, length);,您将丢失对刚刚 malloced 内存的引用。

如果initNode malloc是一 block 新的内存,它“只是”内存泄漏,那么您应该删除中的malloc >addTail.

否则,我担心 initNode 返回局部变量的地址,à la

node * initNode(int val, int len) {
node new;
new.nodeValue = val;
new.nodeLength = len;
new.next = NULL;
return &new;
}

如果 initNode 看起来与此类似,则会导致问题,因为函数一返回,地址就会变得无效。但如果 initNode 看起来像那样,你的编译器应该警告你。

无论如何,在没有看到 initNode 代码的情况下,我无法诊断原因。

但是如果您将 addTail 更改为

void addTail (node *head, int value, int length) {
if (head == NULL) { // violation of contract, die loud
exit(EXIT_FAILURE);
}
node *current = head;
node *newNode = malloc(sizeof(node));
if (newNode == NULL) {
exit(EXIT_FAILURE); // or handle gracefully if possible
}
newNode->nodeValue = value;
newNode->nodeLength = length;
newNode->next = NULL;

while (current->next != NULL)
current = current->next;

current->next = newNode;
}

它应该可以工作。

但是,由于您有指向列表中第一个和最后一个节点的指针,因此使用 back 指针追加新节点会更有效,

void add(queue *currentQueue, int data){
node *newNode = malloc(sizeof *newNode);
if (newNode == NULL) {
exit(EXIT_FAILURE); // or handle gracefully if possible
}
newNode->nodeValue = data;
newNode->nodeLength = data+5;
newNode->next = NULL;
currentQueue->back->next = newNode;
currentQueue->back = newNode;
}

因为您不需要遍历整个列表来找到末尾。

<小时/>

一个简单的示例程序

#include <stdlib.h>
#include <stdio.h>

struct listNode {
int nodeLength;
int nodeValue;
struct listNode *next;
};

typedef struct listNode node;

struct QueueRecord {
node *list;
node *front;
node *back;
int maxLen;
};
typedef struct QueueRecord queue;

node *createList (){
node *head = NULL;
head = (struct listNode *)malloc(sizeof(node));
head->next = NULL;
return head;
}

void addTail (node *head, int value, int length) {
if (head == NULL) { // violation of contract, die loud
exit(EXIT_FAILURE);
}
node *current = head;
node *newNode = malloc(sizeof(node));
if (newNode == NULL) {
exit(EXIT_FAILURE); // or handle gracefully if possible
}
newNode->nodeValue = value;
newNode->nodeLength = length;
newNode->next = NULL;

while (current->next != NULL)
current = current->next;

current->next = newNode;
}

queue createQueue(int maxLen){
queue newQueue;
newQueue.list = createList();
newQueue.front = newQueue.list;
newQueue.back = newQueue.list;
newQueue.maxLen = maxLen;
return newQueue;
}

void add(queue *currentQueue, int data){
if (currentQueue == NULL) {
exit(EXIT_FAILURE);
}
addTail(currentQueue->list, data, data+5);
currentQueue->back = currentQueue->back->next;
}

int main(void) {
queue myQ = createQueue(10);
for(int i = 1; i < 6; ++i) {
add(&myQ, i);
printf("list: %p\nfront: %p\nback: %p\n",
(void*)myQ.list, (void*)myQ.front, (void*)myQ.back);
}
node *curr = myQ.front->next;
while(curr) {
printf("Node %d %d, Back %d %d\n", curr->nodeValue,
curr->nodeLength, myQ.back->nodeValue, myQ.back->nodeLength);
curr = curr->next;
}
while(myQ.list) {
myQ.front = myQ.front->next;
free(myQ.list);
myQ.list = myQ.front;
}
return 0;
}

按预期工作,也可以使用替代的 add 实现。

关于c - 使用单链表更新队列 adt 中的尾指针时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12771869/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com