【发布时间】:2015-06-01 20:43:35
【问题描述】:
所以我真的很困惑。我正在尝试编写一个 c 方法,该方法允许我将新的“节点”添加到链表的前面。我以前在 C++ 中做过这个,没问题。我很沮丧,因为在编写代码后我很确定我是对的变量的值。代码如下:
真正的功能是:
void addToBeginning(int value, struct node* root){
struct node* newNode;
newNode = malloc( sizeof(struct node));
newNode->value = value;
newNode->next = root;
root = newNode;
}
但这里是完整的代码。我删除了一些内容以使其更简洁(回答此问题不需要的内容,例如 getLength(...) 和 addToPos(...))
#include <stdio.h>
#include <stdlib.h>
struct node {
int value;
struct node* next;
};
void printLinkedList(struct node* root);
void addToEnd(int value, struct node* root);
void addToBeginning(int value, struct node* root);
void addToPos(int pos, int value, struct node* root);
int getLength(struct node* root);
int main(){
/**
TESTING addToBeginning (I know addToEnd works)
**/
struct node *root2;
root2 = malloc( sizeof(struct node));
root2->value = 4;
root2->next = NULL;
/*
root2 = 4 -> 0 -> 0 -> 0 -> 0 -> 0 -> 0
*/
i = 0;
while (i < 5){
addToEnd(0,root2);
i++;
}
printLinkedList(root2);
//printf("Length : %d\n",getLength(root2));
/*
expected root2 = 2 -> 4 -> 0 -> 0 -> 0 -> 0 -> 0
*/
addToBeginning(2, root2);
printLinkedList(root2);
/*
obtained root2 = 4 -> 0 -> 0 -> 0 -> 0 -> 0 -> 0
*/
//printf("Length : %d\n",getLength(root2));
return(0);
}
void printLinkedList(struct node* root){
while(root != NULL){
if (root->next != NULL){
printf("%d, ",root->value);
root=root->next;
} else {
printf("%d\n",root->value);
root=root->next;
}
}
}
void addToEnd(int value, struct node* root){
/*
Set up new node
*/
struct node* newNode = malloc( sizeof(struct node));
newNode->value = value;
newNode->next = NULL;
/*
Check if empty linked list first
*/
if (root->next == NULL){
root->next = newNode;
} else {
/*
Find the last node
*/
struct node* current = root;
while(current->next != NULL){
current = current->next;
}
current->next = newNode;
}
}
void addToBeginning(int value, struct node* root){
struct node* newNode;
newNode = malloc( sizeof(struct node));
newNode->value = value;
newNode->next = root;
root = newNode;
}
令人困惑的是,我觉得在
newNode->next = root;
root = newNode;
lines...所以我包括在调试步骤中获得的地址:
所以...在addToBeginning(int value, struct node* root){...} 函数中,我将逐步完成:
执行后:
struct node* newNode;
newNode = malloc( sizeof(struct node));
root和newNode的地址和值是:
root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = NULL
newNode->value = 0
执行后:
newNode->value = value;
root和newNode的地址和值是:
root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = NULL
newNode->value = 2
执行后:
newNode->next = root;
root和newNode的地址和值是:
root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = 0x0000000100103c60
newNode->value = 2
执行后:
root = newNode;
root和newNode的地址和值是:
root = 0x0000000100103cc0
root->next = 0x0000000100103c60
root->value = 2
newNode = 0x0000000100103cc0
newNode->next = 0x0000000100103c60
newNode->value = 2
我意识到问题在于 *root 是通过引用传递的,所以我需要做的是更改存储在位置 0x0000000100103c60 中的对象的值,因此任何有关如何做到这一点的建议将不胜感激。
【问题讨论】:
-
你在insert函数中修改了
root的本地副本;您不修改调用代码中的相应值。要么从函数返回列表的新头,要么将指向根节点的指针传递给函数,以便可以在函数中修改指向根节点的指针。在 SO 上有很多很多类似的问题与相同的基本问题。 -
宾果游戏。谢谢@JonathanLeffler,我只需要听到一个指向指针的指针!
-
天啊!!!一个带有调试步骤的链表问题解释!投赞成票。我得买一张彩票。
-
请注意,
main()中用于创建节点的代码是struct node *root2; root2 = malloc( sizeof(struct node)); root2->value = 4; root2->next = NULL;,并且您的addToBeginning()和addToEnd()代码中的代码几乎相同。这可能应该被抽象成一个struct node *newElement(int value);函数。然后,您可以在一处添加对malloc()故障的错误检查,而不必在三个不同的地方进行。
标签: c pointers linked-list singly-linked-list