c中的链表添加到前面
Linked List in c add to front
所以我真的很困惑。我正在尝试编写一个 c 方法,允许我将一个新的 "node" 添加到链表的前面。我以前用 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;
行...所以我包括了在我的调试步骤中获得的地址:
所以...在 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
中的对象的值所以关于如何做的任何建议将不胜感激。
函数中
void addToBeginning(int value, struct node* root){
struct node* newNode;
(...)
root = newNode;
}
struct node *root2;
addToBeginning(2, root2);
您将新地址分配给本地根指针。该指针与您的原始根指针具有相同的值,但它是它的副本。因此,在函数 returns.
之后更改函数内部的变量对原始根没有影响
相反,您必须逐个指针传递指针:
void addToBeginning(int value, struct node **root){
struct node* newNode;
(...)
*root = newNode;
}
struct node *root2;
addToBeginning(2, &root2);
附加信息
这可能令人惊讶。当你想改变原始变量时,你不是总是将指针传递给函数吗?嗯,是的,但是它指向的是变量——而不是指针本身。在这里,假设您的原始函数采用指针(不是指向指针的指针),您仍然可以使用 *root2 = x
更改 root2 指向的原始节点或使用 root2->member = y
更改该节点的成员。它会起作用,因为您更改了指向的变量(即使它们是指针 - 您可以更改这些指针 [它们指向的地址] 因为您有一个指向它们的指针并且您取消引用该指针)。
指针作为变量也是如此。如果要更改原始指针,则必须指向它并更改指向的变量,在这种情况下为原始指针。
你需要
void addToBeginning(int value, struct node** root)
注意两个 *
代表 root
这允许您在此函数之外修改 root
。
所以我真的很困惑。我正在尝试编写一个 c 方法,允许我将一个新的 "node" 添加到链表的前面。我以前用 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;
行...所以我包括了在我的调试步骤中获得的地址:
所以...在 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
中的对象的值所以关于如何做的任何建议将不胜感激。
函数中
void addToBeginning(int value, struct node* root){
struct node* newNode;
(...)
root = newNode;
}
struct node *root2;
addToBeginning(2, root2);
您将新地址分配给本地根指针。该指针与您的原始根指针具有相同的值,但它是它的副本。因此,在函数 returns.
之后更改函数内部的变量对原始根没有影响相反,您必须逐个指针传递指针:
void addToBeginning(int value, struct node **root){
struct node* newNode;
(...)
*root = newNode;
}
struct node *root2;
addToBeginning(2, &root2);
附加信息
这可能令人惊讶。当你想改变原始变量时,你不是总是将指针传递给函数吗?嗯,是的,但是它指向的是变量——而不是指针本身。在这里,假设您的原始函数采用指针(不是指向指针的指针),您仍然可以使用 *root2 = x
更改 root2 指向的原始节点或使用 root2->member = y
更改该节点的成员。它会起作用,因为您更改了指向的变量(即使它们是指针 - 您可以更改这些指针 [它们指向的地址] 因为您有一个指向它们的指针并且您取消引用该指针)。
指针作为变量也是如此。如果要更改原始指针,则必须指向它并更改指向的变量,在这种情况下为原始指针。
你需要
void addToBeginning(int value, struct node** root)
注意两个 *
代表 root
这允许您在此函数之外修改 root
。