像这样做的GLib库来比较两个单链表节点:
typedef struct _GSList {
_GSList *link;
void *data;
} GSList;
int g_sListPosition(GSList *list, GSList *llink) {
int cnt = 0;
while(list) {
if(list == llink) // Note here
return cnt;
cnt++;
list = list->link;
}
return -1;
}
但是当我比较这样的节点时。它返回false:
int main(void) {
GSList *list = NULL, *list2 = NULL;
list2 = g_sListAppend(list2, "def");
list = g_sListAppend(list, "abc");
list = g_sListAppend(list, "def");
list = g_sListAppend(list, "ghi");
printf("%d", g_sListPosition(list, list2)); // Return -1 ?
}
那么,这里有什么比较(在DOC中,它写的获取GSList中给定元素的位置),一个节点或列表中包含的数据?
编辑:感谢所有给定的,我的错误实际上是以错误的方式做到了。我必须比较列表的相同实例。
答案 0 :(得分:2)
由于list
和llink
是节点地址,我们不能拥有两个具有相同地址的不同节点,因此找到llink
在list
内开始的非常简单的技术}(第一)。
假设list
传递给函数就像:
// 0 1 2 3 4
list---->[]-->[]-->[]-->[]-->[]---null
23 42 18 102 324
addresses are assumption
如果llink
值为18
,则函数返回2
,因为llink
是list
中的第三个节点。
如果找不到llink
则会返回-1
。
(就像数组索引以0
列表中的0
函数计数数字节点开头一样
正如您所说,我正在评论代码:
int cnt = 0; // initial value of node_count is 0
while(list) { // search while list not NULL (till end)
if(list == llink) // if `llink` is a node in `list`
return cnt; // return node number
cnt++; // else it may be next node
list = list->link;
}
// control comes here if list == NULL, means llink not found
return -1; // not found so return -1
// negative number can't be a position
<强>注释:强>
我的意思是,如何测试它如果真的给出正值
按以下方式调用您的函数:
g_sListPosition(list, list->link->link->link);
// 0 1 2
它将返回2
。
但请注意,您的列表应包含3
个节点。
答案 1 :(得分:2)
头部list2
+--------+
| def |--->X
+--------+
arr1
当函数分配节点时,它将分配一个具有节点大小的空闲内存位置,然后在节点的数据部分中分配字符串(必须在其中分配字符串)。
头部list
+--------+ +--------+ +--------+
| abc |--->| def |--->| ghi |--->X
+--------+ +--------+ +--------+
addr2 addr3 addr4
此处每次将字符串附加到链接列表时,都会分配一个新节点,并在数据部分中复制该字符串。请注意,每次分配新节点时,节点的地址都不同。
在上面的情况中,具有数据“def”的第一个列表具有地址addr1
,而第二个列表具有数据“def”的节点具有地址addr3
。因此,如果您尝试将这两个节点与==
运算符进行比较,则自然比较结果将为false,因为相等性将比较节点的地址,这些节点的位置不同,因此返回false。
如果要特别匹配节点中的数据,则需要专门对其进行比较。也就是说,访问list
中的每个节点,并将数据部分与其他节点(list1
)进行比较。
另一方面,如果要在特定链表中放置节点地址,则可以使用该地址进行比较。例如,如果您遍历列表直到结束并获取具有地址addr4
的“ghi”的最后一个节点的地址,那么您可以使用此地址稍后比较列表中的特定节点,前提是此节点尚未使用相同数据释放和重新创建。在这种情况下,您甚至可以清楚地看到此节点内的数据发生变化,地址将保持不变。
答案 2 :(得分:0)
我发现,我们必须实际给出列表的相同实例。以下是一个例子:
int main(void) {
RSList *list = NULL;
list = r_sListAppend(list, "abc");
list = r_sListAppend(list, "def");
list = r_sListAppend(list, "ghi");
RSList *list2 = list;
int i = 2;
while(i--) {
list2 = list2->link;
}
printf("%d", r_sListIndexOf(list, list2)); // Print 2
}