我正在为uni工作,我需要找到图表的总和。
要做到这一点,我相信我需要一个链表,我可以用它来记住访问过的节点。我有链接列表正常工作,但我无法使用包含函数。这是我的代码:
struct listnode
{
struct N *val;
struct listnode *next;
};
int contains(struct listnode *head,struct N* value)
{
struct listnode *current = head;
while (current)
{
if ((current -> val) == value)
{
return 1;
}
current = current -> next;
}
return 0;
}
注意:N是图表的节点。
任何人都可以看到我正在做的任何问题吗?
编辑:当N *值在列表中时,包含函数应返回1,否则为0
EDIT2:
我有推送功能:
void push(struct listnode *head,struct N *value)
{
if (head)
{
struct listnode *current = head;
while (current->next)
{
current = current -> next;
}
current->next = malloc(sizeof(struct listnode*));
current->next->val = value;
current->next->next = NULL;
}
else
{
head = malloc(sizeof(struct listnode*));
if (head)
{
head -> val = value;
head -> next = NULL;
}
else
{
printf("error");
exit(0);
}
}
}
我希望以下行返回1:
contains(push(visited,p),p);
其中p是指向结构N的指针,访问的是我的全局链表
EDIT3:
这是我认为应该起作用的最终总和函数,但不是因为包含。
long sum(struct N *p)
{
if (p)
{
if (contains(visited,p) == 0) //if p hasnt been visited
{
push(visited,p); //make it visited
return (p -> data) + sum(p -> x) + sum(p -> y) + sum(p -> z);
}
else
{
return 0;
}
}
else
{
return 0;
}
}
答案 0 :(得分:2)
您的包含功能似乎没问题。问题是您始终向其传递NULL
列表,这是由错误的push
函数引起的。您需要在push
中返回,或者传入一个指向另一个间接级别的指针,这样您就可以在head
之外分配push
。另一个可能的改进是注意到无论你传入什么,malloc
和新节点的初始化实际上是相同的。
最后,主要问题是,最有可能导致段错误的是你为节点指定了足够的空间,而不是节点本身。
以下是一个例子:
#ifdef BY_INDIRECTION
#define RET_TYPE void
#define IN_TYPE struct listnode **
#else
#define RET_TYPE struct listnode *
#define IN_TYPE struct listnode *
#endif
RET_TYPE push(IN_TYPE head, struct N *value)
{
struct listnode *current, **next;
if(head)
{
for(current = head; current->next; current = current->next) ;
next = &(current->next);
}
else
{
#ifdef BY_INDIRECTION
next = head;
#else
next = &head;
#endif
}
*next = malloc(sizeof(struct listnode));
if(!*next) {
printf("error");
exit(0);
}
(*next)->val = value;
(*next)->next = NULL;
#ifndef BY_INDIRECTION
return head
#endif
}
我在这里提出了两条建议。如果您想阅读我们使用间接的方法(传入listnode **
并返回void
),请选择定义BY_INDIRECTION
的路径。如果您希望返回head
(并仅传入常规listnode *
),请阅读未定义BY_INDIRECTION
的路径。
后一种方法具有返回值,因此可用于编写缩写形式,如if(contains(push(head, value), value)) { ... }
。前一种方法没有,所以你必须这样做
push(&head, value);
if(contains(head, value)) { ... }
我建议使用间接方法,因为在放入值之后,您希望检查包含的实例非常少。
答案 1 :(得分:0)
这个比较:
if ((current -> val) == value)
它正在比较指针。如果您以这种方式致电contains()
功能......
...
struct N val_to_find;
...
result = contains (list, &val_to_find);
即使val_to_find
的内容与指针存储在列表中的任何结构的内容相同,也永远不会找到该值。
如果您对contains()
的意图是找到具有相同数据的节点,而不仅仅是相同的指针,我建议你这样:
if (struct_n_comparing_function (current -> val, value) == EQUAL) ...
struct_n_comparing_function
应该有以下原型:
int struct_n_comparing_function (struct N *a, struct N *b);
比较a
和b
指向的两个结构的内容,如果EQUAL
指向的结构的所有字段具有相同的值,则返回a
由b
指向的结构字段。