我正在尝试实现从链接列表中删除节点的功能。到目前为止,我只可以删除list(3)的第一个节点。
我试图从delete转到for循环,我认为内存分配不正确,我已经苦苦挣扎了几天,我听不懂,请帮我一下,这是我收到的主题从大学。
#include <stdio.h>
#include <stdlib.h>
typedef struct nod
{
int key;
struct nod *urm;
} NOD;
NOD *first=0,*last=0;
void add(int x)
{
NOD *p=(NOD*)malloc(sizeof(NOD));
p->key=x;
p->urm=0;
if(0==first)
{
first=p;
last=p;
}
else{
last->urm=p;
last=p;
}
}
void delete(int x)
{
NOD *q,*p;
if(first->key==x)
{
p=first;
first=first->urm;
free(p);
}
else{
for(p=q=first;p=0;q=p,p=p->urm)
{
if(p->key==x)
{
q->urm=p->urm;
if(p==last)
{
last=q;
}
free(p);
}
}
}
}
void show()
{
for(NOD *p=first;p!=0;p=p->urm)
{
printf("%d ",p->key);
}
printf("\n");
}
int main()
{
add(3);
add(1);
add(2);
add(5);
show();
delete(2);
show();
return 0;
}
答案 0 :(得分:1)
对于初学者来说,您显示的代码不是C ++代码。这是C代码。
定义诸如first
和last
之类的全局变量以及函数何时依赖于全局变量是一个坏主意。在这种情况下,您不能在一个程序中创建多个列表。
对于功能delete
,然后通常具有未定义的行为。可以将其称为空列表。
此外,在此循环中
for(p=q=first;p=0;q=p,p=p->urm)
条件表达式中有一个错字。您正在使用赋值运算符而不是比较运算符。
您可以忽略列表仅包含一个节点的情况,因为在这种情况下,列表不会更新最后一个节点。
尽管如此,使用函数删除功能的方式还是可以这样。
void delete(int x)
{
if ( first )
{
if ( first->key == x )
{
NOD *tmp = first;
first = first->urm;
free( tmp );
if ( first == NULL ) last = NULL;
}
else
{
NOD *p = first;
while ( p->urm != NULL && p->urm->key != x )
{
p = p->urm;
}
if ( p->urm != NULL )
{
NOD *tmp = p->urm;
p->urm = p->urm->urm;
free( tmp );
if ( p->urm == NULL ) last = p;
}
}
}
}
这是一个演示程序。
#include <stdio.h>
#include <stdlib.h>
typedef struct nod
{
int key;
struct nod *urm;
} NOD;
NOD *first=0,*last=0;
void add(int x)
{
NOD *p=(NOD*)malloc(sizeof(NOD));
p->key=x;
p->urm=0;
if(0==first)
{
first=p;
last=p;
}
else{
last->urm=p;
last=p;
}
}
void delete(int x)
{
if ( first )
{
if ( first->key == x )
{
NOD *tmp = first;
first = first->urm;
free( tmp );
if ( first == NULL ) last = NULL;
}
else
{
NOD *p = first;
while ( p->urm != NULL && p->urm->key != x )
{
p = p->urm;
}
if ( p->urm != NULL )
{
NOD *tmp = p->urm;
p->urm = p->urm->urm;
free( tmp );
if ( p->urm == NULL ) last = p;
}
}
}
}
void show()
{
for(NOD *p=first;p!=0;p=p->urm)
{
printf("%d ",p->key);
}
printf("\n");
}
int main()
{
add(10);
add(20);
add(30);
add(40);
show();
delete(30);
show();
add( 50 );
add( 60 );
add( 70 );
add( 80 );
show();
delete(80);
show();
return 0;
}
其输出为
10 20 30 40
10 20 40
10 20 40 50 60 70 80
10 20 40 50 60 70
答案 1 :(得分:0)
通过使用指向{{1}的指向指针的和指向{em>的指向的指针,可以大大简化从列表中删除节点的过程。 }遍历列表。这样,您可以将当前地址的节点设置为NOD
,而无需跟踪列表中的前一个节点,例如
NOD
请参见Linus on Understanding Pointers,以进一步讨论除了使用指向节点的指针之外,还使用节点地址的优点。
答案 2 :(得分:-1)
我认为删除函数中的for循环条件不正确:
?body
只要改变条件,它就应该起作用。