C-双链表-节点';s的内容不正确(难以解释)

C-双链表-节点';s的内容不正确(难以解释),c,linked-list,doubly-linked-list,C,Linked List,Doubly Linked List,我发现在标题中很难解释这一点,但实际上却没有显示代码和问题……所以,就这样。我省略了那些有效的方法,所以不需要太多的阅读 #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <ctype.h> struct tnode { struct tnode *prev; char *word; st

我发现在标题中很难解释这一点,但实际上却没有显示代码和问题……所以,就这样。我省略了那些有效的方法,所以不需要太多的阅读

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <ctype.h>

struct tnode {
    struct tnode *prev;
    char *word;
    struct tnode *next;
};

struct tnode *talloc(void)
{
    ...
}

struct tnode *addlist(struct tnode *p, char *w)
{
    ...
}

void removelist(struct tnode *p, char *w)
{
    while (1)
    {
        if (strcmp(p->word,w) == 0)
        {
            p->next->prev = p->prev;
            p->prev->next = p->next;
            goto out;
        }
        else if (strcmp(p->word,w) > 0)
        {
            p = p->prev;
        }
        else p = p->next;
    }
out:;
    return p;
}

void tprint(struct tnode *root)
{
    ...
}

main()
{
    struct tnode *root;
    root = talloc();
    root->word = "doberman";
    root->next = talloc();
    root->prev = talloc();
    //I am using a blank string at the beginning and end instead of leaving it NULL. When I tried leaving it NULL, I would get inaccessability errors.
    root->next->word = "";
    root->prev->word = "";
    //I don't remember why I made "current" but it is working so I don't want to mess with it.
    struct tnode *current;
    current = talloc();
    current = root;
    current = addlist(root, "giraffe");
    current = addlist(root, "gemini");
    current = addlist(root, "apple");
    current = addlist(root, "azure");
    current = addlist(root, "rabbit");
    current = addlist(root, "zambia");
    current = addlist(root, "viking");
    current = addlist(root, "cat");
    current = addlist(root, "dog");
    current = addlist(root, "tree");
    current = addlist(root, "domino");
    removelist(root, "azure");
    tprint(root);
}
#包括
#包括
#包括
#包括
#包括
结构节点{
结构tnode*prev;
字符*字;
结构tnode*下一步;
};
结构tnode*talloc(无效)
{
...
}
struct tnode*addlist(struct tnode*p,char*w)
{
...
}
void removelist(结构tnode*p,char*w)
{
而(1)
{
如果(strcmp(p->word,w)==0)
{
p->next->prev=p->prev;
p->prev->next=p->next;
出去;
}
否则如果(strcmp(p->word,w)>0)
{
p=p->prev;
}
否则p=p->next;
}
外:;
返回p;
}
void tprint(struct tnode*root)
{
...
}
main()
{
结构tnode*根;
root=talloc();
root->word=“杜宾”;
root->next=talloc();
root->prev=talloc();
//我在开头和结尾使用空白字符串,而不是将其保留为NULL。当我尝试将其保留为NULL时,会出现不可访问性错误。
根->下一步->单词=”;
root->prev->word=“”;
//我不记得为什么我做了“电流”,但它是工作的,所以我不想弄乱它。
结构tnode*当前;
电流=塔洛克();
电流=根;
当前=添加列表(根,“长颈鹿”);
当前=地址列表(根,“双子座”);
当前=添加列表(根,“苹果”);
当前=地址列表(根,“azure”);
当前=添加列表(根,“兔子”);
当前=地址列表(根,“赞比亚”);
当前=地址列表(根,“viking”);
当前=添加列表(根,“cat”);
当前=添加列表(根,“狗”);
当前=添加列表(根,“树”);
当前=添加列表(根,“domino”);
removelist(根,“azure”);
tprint(root);
}
removelist方法当前正在删除2-4项(而不是1项)中超出其应删除的内容。当我在bebugger中逐步执行该方法时,我注意到“p->word”与“p”不匹配

例如,调试器会说“p->word”当前是“doberman”,然后告诉我“p”当前包含“apple”


我的问题是:这怎么可能?如果“p”是苹果的节点,“p->word”怎么可能是杜宾呢?它真的把这个方法搞砸了,因为它会认为它是在正确的位置进行删除,而事实上它不是。

当比较是否应该删除你的

if (strcmp(p->word,w) > 0)
当不匹配的第一个字符在ptr1中的值大于ptr2中的值时,将返回true

我假设您想要删除匹配项,因此这是一个问题,但不是问题所在。在调用remove之前是否尝试打印列表以确保添加了所有项目?当你一步一步走完当你点击goto语句时会发生什么

if (strcmp(p->word,w) > 0)
应该是

if (strcmp(p->word,w) == 0)

我认为您仍然需要将p->next和p->prev设置为NULL。否则,p仍然可以被遍历。也许这会给你带来有趣的结果。

我最后怀疑的一件事就是打印方法。似乎我在这里问的每一个问题都是这样结束的……答案与我在这里问的问题无关,但所有的答案仍然引导我找到解决方案


无论如何,感谢您的帮助。

通常情况下,
remove
函数会删除与给定字符串匹配的节点。因此,您可以扫描链表,直到strcmp()==0,然后删除该节点。您的代码将删除第一个“大于”给定字符串的单词。脱离主题:不要使用
goto
来打破循环。相反,使用
break
来打破循环。啊,对了,这是个问题。这只是我在尝试解决最初的问题时所遗留下来的东西,但这并不能解决我所遇到的问题。add方法在我添加remove方法之前就已经起作用了,但我只是用单个字符对它进行了测试。原来我以为被拿走的东西根本就不在那里。