c - 将元素添加到 C 中链接列表的特定链接列表
问题描述
假设我们有以下结构:
typedef struct link {
char link[MAXLINK];
struct link *next;
} LinkT;
typedef struct node {
char keyword[MAXKEY];
LinkT *links;
struct node *next;
} NodeT;
在主要功能中,我添加了一些新关键字和指向它的链接。打印整个列表时得到的输出是:
Asteroid
Link-45
Link-23
Earth
Link-2
Moon
Link-3
Link-1
我想向地球添加一个新的链接 4。所以输出看起来像这样:
Asteroid
Link-45
Link-23
Earth
Link-2
Link-4
Moon
Link-3
Link-1
我的想法是有一个findLink
遍历关键字列表的函数,然后关键字匹配,遍历链接列表,如果没有找到链接,我添加一个新的。
但是,问题是当我运行下面的代码时,它永远不会完成,不输出任何东西(冻结?),我必须强制退出它。
如果我删除最后添加的关键字和链接,它会运行但不正确并打印该链接不在列表中。类似findKeyword
的功能也一样 - 打印不在列表中的关键字。
如何修复代码以使其适用于任何列表?
代码:
NodeT *addNewKeyword(NodeT **list, char *keyword) {
NodeT *new = malloc(sizeof(NodeT));
assert(new != NULL);
strcpy(new->keyword, keyword);
new->next = *list;
*list = new;
return 0;
}
LinkT *addNewLink(NodeT *list, char *link) {
LinkT *new = malloc(sizeof(LinkT));
assert(new != NULL);
strcpy(new->link, link);
new->next = list->links;
list->links = new;
return 0;
}
NodeT *findKeyword(NodeT *list, char *keyword) {
NodeT *current = list;
while (current != NULL) {
if (strcmp(current->keyword, keyword) == 0) {
return current;
}
current = current->next;
}
return NULL;
}
void *findLink (NodeT *list, char *keyword, char *link) {
NodeT *current = list;
while (current != NULL) {
if (strcmp(current->keyword, keyword) == 0) {
LinkT *currentLink = list->links;
while (currentLink != NULL) {
if (strcmp(currentLink->link, link) == 0) {
return currentLink;
}
currentLink = list->links->next;
}
return NULL;
}
current = current->next;
}
return NULL;
}
void *printList(NodeT *listNode) {
while (listNode != NULL) {
printf("%s\n", listNode->keyword);
LinkT *listLink = listNode->links;
if (listLink == NULL) {
printf("List is empty.\n");
} else {
while (listLink != NULL) {
printf(" %s\n", listLink->url);
listLink = listLink->next;
}
}
listNode = listNode->next;
}
return 0;
}
int main() {
NodeT *wordsList = NULL;
addNewKeyword(&wordsList, "Moon");
addNewLink(wordsList, "Link-1");
addNewLink(wordsList, "Link-3");
addNewKeyword(&wordsList, "Earth");
addNewLink(wordsList, "Link-2");
/* runs after removing following lines: */
// addNewKeyword(&wordsList, "Asteroid");
// addNewLink(wordsList, "Link-23");
// addNewLink(wordsList, "Link-45");
if (findKeyword(wordsList, "Moon") == 0) {
printf("Keyword is in list.\n");
} else {
printf("Keyword is not in list.\n");
}
if (findLink(wordsList, "Moon", "Link-1") == NULL) {
printf("Link is not in list.\n");
addNewLink(wordsList, "Link-1");
} else {
printf("Link is in list.\n");
}
printList(wordsList);
return 0;
}
编辑 1
我正在从函数类型 void 返回一个节点,这可能是无法按预期工作的原因。findLink
功能需要是什么类型?
编辑 2
正如 Sahin 在回答中指出的那样,我更新了findLink
函数,现在程序运行了,但是在不正确的位置添加了一个元素。主代码变化:
int main() {
...
addNewKeyword(&wordsList, "Moon");
addNewLink(wordsList, "Link-1");
addNewLink(wordsList, "Link-3");
addNewKeyword(&wordsList, "Earth");
addNewLink(wordsList, "Link-2");
addNewKeyword(&wordsList, "Asteroid");
addNewLink(wordsList, "Link-23");
addNewLink(wordsList, "Link-45");
if (findLink(wordsList, "Earth", "Link-4") == NULL) {
printf("Link is not in list.\n");
addNewLink(wordsList, "Link-4");
} else {
printf("Link is in list.\n");
}
...
}
输出:
Link is not in list.
Asteroid
Link-4
Link-45
Link-23
Earth
Link-2
Moon
Link-3
Link-1
解决方案
void *findLink (NodeT *list, char *keyword, char *link) {
NodeT *current = list;
while (current != NULL) {
if (strcmp(current->keyword, keyword) == 0) {
LinkT *currentLink = current->links;//An error is here, you always look for the same list.
while (currentLink != NULL) {
if (strcmp(currentLink->link, link) == 0) {
return currentLink;
}
currentLink = currentLink->next;//The other error is here
}
return NULL;
}
current = current->next;
}
return NULL;
}
我猜你的错误就在这里,你需要获取 currentLink 的下一个,因为同一个节点的下一个总是相同的。完成这些更正后,您需要测试代码,然后我们可以再次查看结果。
编辑:响应编辑2:
NodeT *addNewKeyword(NodeT **list, char *keyword) {
NodeT *new = malloc(sizeof(NodeT));
assert(new != NULL);
strcpy(new->keyword, keyword);
new->next = *list;
*list = new; //This row
return 0;
}
在我发表评论的行中,您更改了参数内的值,并且列表变量中的值发生了变化。由于您最后使用“Asteroid”调用 addNeKeyword,因此会将新链接添加到那里。所以,请详细说明。你真正想要的是什么?
推荐阅读
- javascript - Firebase:用于跨多个集合搜索的 Firestore 索引
- python - 如何从python中的列表中删除''
- c++ - Qt3D 几何着色器在 QML 中工作,但在 C++ 中不工作
- html - CSS Grid:折叠宽度仅为 1 列
- angular - Angular 拦截器调度操作以更改状态并在 next.handle 之前等待此更改
- amazon-web-services - 试图让红移用户访问 IAM 角色,受信任的实体列表已更新,但仍然出现相同的错误
- kotlin - emre1512 在 Kotlin 中创建 Noty RelativeLayout
- scala - 为 gradle 多模块项目问题设置覆盖范围
- javascript - 从本地 a href 中提取查询字符串
- javascript - Number() 在字符串上使用时返回 Nan