在C语言中递归搜索链表
我是C语言的新手,我曾尝试编写一个递归搜索链表的方法,但没有成功。如果在链表的任何节点中都找不到名称,则函数返回0,如果找到1,则返回1。我似乎进入了一个无限循环。任何帮助都将不胜感激在C语言中递归搜索链表,c,list,search,recursion,C,List,Search,Recursion,我是C语言的新手,我曾尝试编写一个递归搜索链表的方法,但没有成功。如果在链表的任何节点中都找不到名称,则函数返回0,如果找到1,则返回1。我似乎进入了一个无限循环。任何帮助都将不胜感激 #include<stdlib.h> #include<string.h> struct node { char name[1000]; struct node *next; }; int contains(const struct node *pNode, const
#include<stdlib.h>
#include<string.h>
struct node
{
char name[1000];
struct node *next;
};
int contains(const struct node *pNode, const char *name)
{
int i;
int length = strlen(name);
int isEqual = 0;
while (pNode != NULL)
{
isEqual = 1;
for (i = 0; i < length; i++)
{
if (pNode->name[i] != name[i])
{
isEqual = 0;
}
}
}
contains(pNode->next, name);
return isEqual;
}
main()
{
struct node node1 = { "Sam", NULL };
struct node *node1Ptr = &node1;
struct node node2 = { "Anna", node1Ptr };
struct node *node2Ptr = &node2;
struct node node3 = { "Adam", node2Ptr };
struct node *node3Ptr = &node3;
int n, k;
// testing for a name that is the list
n = contains(node3Ptr, "Sam");
printf("%d\n", n);
// testing for a name that is not in the list
k = contains(node3Ptr, "Max");
printf("%d\n", k);
}
#包括
#包括
结构节点
{
字符名[1000];
结构节点*下一步;
};
int contains(常量结构节点*pNode,常量字符*name)
{
int i;
int length=strlen(名称);
int isEqual=0;
while(pNode!=NULL)
{
等质量=1;
对于(i=0;iname[i]!=name[i])
{
等质量=0;
}
}
}
包含(pNode->next,name);
回报均等;
}
main()
{
结构节点node1={“Sam”,NULL};
结构节点*node1Ptr=&node1;
结构节点node2={“Anna”,node1Ptr};
结构节点*node2Ptr=&node2;
结构节点node3={“Adam”,node2Ptr};
结构节点*node3Ptr=&node3;
int n,k;
//正在测试列表中的名称
n=包含(node3Ptr,“Sam”);
printf(“%d\n”,n);
//测试不在列表中的名称
k=包含(节点3ptr,“最大”);
printf(“%d\n”,k);
}
您的无限循环是以下行的直接结果:
while (pNode != NULL)
因为你永远不会改变pNode
所指向的内容。基本上,您是在反复检查Sam
。。。事实上,您甚至都无法进行递归调用
相反,你会想要一个
if(pNode != NULL)
检查,如果没有,请检查字符串。如果找到字符串,则返回1,否则返回递归调用
如果
pNode==NULL
您希望返回0。您的无限循环是以下行的直接结果:
while (pNode != NULL)
int contains(const struct node *pNode, const char *name)
{
if (pNode == NULL) // Recursive base-case: If there is no Node,
{ // we are at the end of the list, and the name was never found.
return 0; // Therefore, return 0
}
// If this node matches the name, return 1.
// If this node does NOT match the name, check the next node.
return !strcmp(pNode->name, name)? 1 : contains(pNode->next, name);
}
因为你永远不会改变pNode
所指向的内容。基本上,您是在反复检查Sam
。。。事实上,您甚至都无法进行递归调用
相反,你会想要一个
if(pNode != NULL)
检查,如果没有,请检查字符串。如果找到字符串,则返回1,否则返回递归调用
如果pNode==NULL
您希望返回0
int contains(const struct node *pNode, const char *name)
{
if (pNode == NULL) // Recursive base-case: If there is no Node,
{ // we are at the end of the list, and the name was never found.
return 0; // Therefore, return 0
}
// If this node matches the name, return 1.
// If this node does NOT match the name, check the next node.
return !strcmp(pNode->name, name)? 1 : contains(pNode->next, name);
}
如果您想要一个非常紧凑的表单:
// Untested, but I think it works... or is at least close.
int contains(const struct node *pNode, const char *name)
{
return pNode? (!strcmp(pNode->name, name) || contains(pNode->next, name)) : pNode;
}
如果您想要一个非常紧凑的表单:
// Untested, but I think it works... or is at least close.
int contains(const struct node *pNode, const char *name)
{
return pNode? (!strcmp(pNode->name, name) || contains(pNode->next, name)) : pNode;
}
如果到达endof列表,则不应调用contain函数,但应无限次地调用它。 在通话前添加以下内容:
if (pNode ->next != null)
contains(pNode->next,name);
您还需要停止它调用contain,如果它调用了项目,那么您的条件如下:
if (pNode ->next != null && !isEqual)
contains(pNode->next,name);
如果到达endof列表,则不应调用contain函数,但应无限次地调用它。 在通话前添加以下内容:
if (pNode ->next != null)
contains(pNode->next,name);
您还需要停止它调用contain,如果它调用了项目,那么您的条件如下:
if (pNode ->next != null && !isEqual)
contains(pNode->next,name);
在pnode为NULL之后的contains方法中,再次调用导致无限循环的函数 修改如下
if(pnode== NULL) {
return 0;
}
在pnode为NULL之后的contains方法中,再次调用导致无限循环的函数 修改如下
if(pnode== NULL) {
return 0;
}
您的函数可以简明扼要地写为:
#include <string.h>
...
int contains(const struct node *pNode, const char *name)
{
if(pNode == NULL)
return 0;
if(strcmp(pNode->name, name) == 0)
return 1;
return contains(pNode->next, name);
}
#包括
...
int contains(常量结构节点*pNode,常量字符*name)
{
if(pNode==NULL)
返回0;
if(strcmp(pNode->name,name)==0)
返回1;
返回包含(pNode->next,name);
}
请注意,代码中对contains()
的递归调用的值从未使用过,因此不会给出任何有用的结果。它的调用在最后无条件完成,这就解释了无限循环
编译时启用了所有(合理的)警告(-Wall
用于GCC和clang),它应该会告诉您许多boo-boo。作为一项个人政策,如果它不是-Wall
干净的,最好有一个好的理由相信我是对的,并且编译器过于热心
您还可以简化数据结构的大部分设置,但这是另一个时间
很高兴您根据需要使用
const
进行装饰。您的函数可以简洁地写成:
#include <string.h>
...
int contains(const struct node *pNode, const char *name)
{
if(pNode == NULL)
return 0;
if(strcmp(pNode->name, name) == 0)
return 1;
return contains(pNode->next, name);
}
#包括
...
int contains(常量结构节点*pNode,常量字符*name)
{
if(pNode==NULL)
返回0;
if(strcmp(pNode->name,name)==0)
返回1;
返回包含(pNode->next,name);
}
请注意,代码中对contains()
的递归调用的值从未使用过,因此不会给出任何有用的结果。它的调用在最后无条件完成,这就解释了无限循环
编译时启用了所有(合理的)警告(-Wall
用于GCC和clang),它应该会告诉您许多boo-boo。作为一项个人政策,如果它不是-Wall
干净的,最好有一个好的理由相信我是对的,并且编译器过于热心
您还可以简化数据结构的大部分设置,但这是另一个时间
很高兴您根据需要使用
const
进行装饰。这就是我修改代码的方式,现在它可以工作了。谢谢大家的帮助,我真的很感激,我还不熟悉strcmp的功能,但我会研究一下。再次感谢你
int contains(const struct node *pNode, const char *name){
int i;
int length = strlen(name);
int isEqual = 0;
if(pNode == NULL){
return isEqual;
}
isEqual = 1;
for (i = 0; i < length; i++)
{
if (pNode->name[i] != name[i])
{
isEqual = 0;
break;
}
}
return isEqual? isEqual : contains(pNode->next, name);
}
int contains(常量结构节点*pNode,常量字符*name){
int i;
int length=strlen(名称);
int isEqual=0;
如果(pNode==NULL){
回报均等;
}
等质量=1;
对于(i=0;iname[i]!=name[i])
{
等质量=0;
打破
}
}
返回isEqual?isEqual:contains(pNode->next,name);
}
这就是我修改代码的方式,现在它可以工作了。谢谢大家的帮助,我真的很感激,而且我还不熟悉str