我正在尝试在列表末尾插入一个新节点。我知道第一种方法是"正确的方法"。 但是我正在尝试使用另一个功能(第二个功能(的另一种方式,但似乎我的列表没有变化,有什么想法吗?
typedef struct listnode *listptr;
struct listnode {
int value;
listptr next;
};
void insert_at_end(listptr *x, int n) {
while ((*x) != NULL) {
x = &((*x)->next);
}
*x = (listptr)malloc(sizeof(struct listnode));
(*x)->next = NULL;
(*x)->value = n;
}
void insert_at_end_2(listptr x, int n) {
listptr newnode = (struct listnode *)malloc(sizeof(struct listnode));
newnode->next = NULL;
newnode->value = n;
while (x != NULL) {
x = x->next;
}
x = newnode;
}
这个函数实现有两个问题。
第一个是该函数处理作为参数传递给函数的原始节点的副本。因此,更改副本对原始参数没有影响。
第二个问题是,在这个循环之后
while (x!=NULL){
x = x->next;
}
x 将等于空。所以下一句话
x =newnode;
不更改最后一个节点旁边的数据成员。因此,该列表将保持不变。
使用未通过引用传递头节点的方法,函数实现可以如下所示。
listptr insert_at_end_2( listptr x, int n )
{
listptr newnode = malloc( sizeof( *listptr ) );
if ( newnode != NULL )
{
newnode->next = NULL;
newnode->value = n;
if ( x == NULL )
{
x = newnode;
}
else
{
listptr current = x;
while ( current->next != NULL )
{
current = current->next;
}
current->next = newnode;
}
}
return x;
}
但是,当通过引用传递头节点时,此实现与第一个实现一样有一个缺点:该函数不报告是否成功分配了新节点。
因此,该函数的更好实现可能如下所示
int insert_at_end( listptr *x, int n )
{
listptr newnode = malloc( sizeof( *listptr ) );
int success = newnode != NULL;
if ( success )
{
newnode->next = NULL;
newnode->value = n;
while ( *x != NULL )
{
x = &( *x )->next;
}
*x = newnode;
}
return success;
}
@Vlad 来自莫斯科 我让你的代码和我的代码相似。所以这行得通。
void insert_at_end_2( listptr x, int n )
{
listptr newnode = (listptr)malloc( sizeof( listptr ) );
newnode->next = NULL;
newnode->value = n;
while ( x->next!= NULL )
{
x = x->next;
}
x->next = newnode;
}