我正在尝试在列表末尾插入一个新节点。我知道第一种方法是“正确的方法”。 但是我正在尝试使用另一个功能(第二个功能)的另一种方法,但是似乎列表没有变化,有什么想法吗?
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;
}
答案 0 :(得分:0)
此函数的实现有两个问题。
第一个是该函数处理作为参数传递给该函数的原始节点的副本。因此,更改副本不会影响原始参数。
第二个问题是在循环之后
while (x!=NULL){
x = x->next;
}
x将等于NULL。所以下一条语句
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;
}
答案 1 :(得分:0)
@来自莫斯科的弗拉德 我使您的代码类似于我的代码。所以这行得通。
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;
}