我的问题是从链接列表中删除节点。
我有两个结构:
typedef struct inner_list
{
int count;
char word[100];
inner_list*next;
} inner_list;
typedef struct outer_list
{
char word [100];
inner_list * head;
int count;
outer_list * next;
} outer_list;
我的问题是从outer_list链表中删除一个节点。例如,当用户entered aaa
要删除时,delete function should find the node with outer_list->word = aaa and delete this node and reconnect the list again
。我尝试了下面的代码来做到这一点。但在找到并删除后,我正在丢失列表。我不知道出了什么问题。请注意,outer_list里面还有一个inner_list链表。
void delnode(outer_list **head,char num[100])//thanks to both Nir Levy and Jeremy P.
{
outer_list *temp, *m;
m=temp=*head; /*FIX #1*/
while(temp!=NULL) {
if(strcmp(temp->word,num)==0) {
if(temp==*head) {
delinner(temp->head); /* FIX#2 */
*head=temp->next;
free(temp);
return;
} else {
delinner(temp->head); /* FIX#2 */
m->next=temp->next;
free(temp);
return;
}
} else {
m=temp;
temp= temp->next;
}
}
printf(" ELEMENT %s NOT FOUND ", num);
}
void delinner(inner_list *head) { /* FIX#2 */
inner_list *temp;
temp=head;
while(temp!=NULL) {
head=temp->next;
free(temp);
temp=head;
}
}
现在我的问题已经更新了。从内部列表中删除元素时,我也尝试从inner_list中删除相同的元素。
例如: - 假设aaa是outer_list链表的一个元素,让我们用outer_list * p指出它 - 这个aaa也可以在inner_list链表中。 (它可以在p-> head或另一个内部列表中。)现在,又是棘手的部分。我尝试使用outer_list删除应用相同的规则,但每当我删除inner_list的head元素时,它都会出错。 这是我试过的:
void delnode2(outer_list *up,inner_list **head,char num[100])
{
inner_list *temp2,*temp, *m;
outer_list *p;
p = up;
while(p!=NULL){m=temp=temp2=p->head;
while(temp!=NULL) {
if(strcmp(temp->word,num)==0) {
if(temp==(*head)) {
*head=temp->next;
free(temp);
return;
} else {
m->next=temp->next;
free(temp);
return;
}
} else {
m=temp;
temp= temp->next;
}
}
p=p->next;
}
printf(" ELEMENT %s NOT FOUND ", num);
}
这里我试图发送节点并检查outer_list元素的所有inner_lists并执行删除,但是当第一个元素被删除时它会崩溃。请询问进一步的信息。我可能会用非常不整洁的词语。
答案 0 :(得分:2)
FIX#1(可选) - 初始化所有变量是一个好习惯。请注意,在这个特定的情况下,因为你已经处理了头部secanrio然后你应该没有问题,因为稍后将m设置为temp,但仍然是..
FIX#2 - 确保在释放节点之前完全删除内部列表。
这是代码(未经测试,抱歉)
void delnode(outer_list *head,char num[100])
{
outer_list *temp, *m;
m=temp=head; /*FIX #1*/
while(temp!=NULL) {
if(strcmp(temp->word,num)==0) {
if(temp==head) {
head=temp->next;
delinner(temp->inner_list); /* FIX#2 */
free(temp);
return;
} else {
m->next=temp->next;
delinner(temp->inner_list); /* FIX#2 */
free(temp);
return;
}
} else {
m=temp;
temp= temp->next;
}
}
printf(" ELEMENT %s NOT FOUND ", num);
}
void delinner(inner_list *head) { /* FIX#2 */
inner_list *temp;
temp=head;
while(temp!=NULL) {
head=temp->next;
free(temp);
temp=head;
}
}
答案 1 :(得分:1)
如果您最终需要删除外部列表的第一个元素,则会出现一个大问题:您永远不会传回列表的新头部。你的原始代码需要改变如下(也包括所有其他好的建议):
void delnode(outer_list **tbd,char num[100]) // pass a pointer to tbd
{
outer_list *temp, *m;
temp = *tbd;
while(temp!=NULL)
{
if(strcmp(temp->word,num)==0)
{
if(temp==*tbd)
{
// Delete the inner list here
*tbd=temp->next;
free(temp);
return;
}
// rest of function
你会这样称呼它:
outer_list* myList;
// lots of code including initialising and adding stuff to the list
delnode(&mylist, wordtoDelete); // note the '&' sign
答案 2 :(得分:0)
m
指针未设置为任何有效地址,并且您的程序会遇到未定义的行为。
为了修复你的实现,使用两个指针 - 一个指向当前元素,另一个指向前一个指针,并在遍历列表时更新它们。你必须将零和一元的情况视为特殊情况 - 小心。
答案 3 :(得分:0)
我认为你没有释放你的inner_list
。你会得到内存泄漏。
答案 4 :(得分:0)
你正在检查单词的if条件不应该是以下内容:
if(strcmp(temp->word, num)==0)
答案 5 :(得分:0)
尝试这个(仅适用于外部列表,它不会释放内部列表):
void delnode(outer_list *head,char num[100])
{
outer_list *temp, *m. *helper;
temp=head;
while(temp!=NULL)
{
if(strcmp(temp->word,num)==0)
{
if(temp==head)
{
head=temp->next;
free(temp);
return;
}
else
{
m = temp;
temp = temp->next;
helper->next = temp; //link the previous item
free(m);
return;
}
}
else
{
helper = temp;
temp= temp->next;
}
}
printf(" ELEMENT %s NOT FOUND ", num);
}