2

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;
    }

但是当我像这样比较节点时。它返回错误:

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 ?
}

那么,这里比较的是什么(在文档中,它写的是获取给定元素在 GSList 中的位置)、节点或列表中包含的数据?

编辑:感谢所有给出的,我的错误我实际上是以错误的方式做的。我必须比较列表的相同实例。

4

3 回答 3

2

带头的清单list2

+--------+
|  def   |--->X
+--------+
   arr1

当函数分配节点时,它将分配一个具有节点大小的空闲内存位置,然后在节点的数据部分(它必须分配字符串)中分配字符串。

带头的清单list

+--------+    +--------+    +--------+
|   abc  |--->|   def  |--->|  ghi   |--->X
+--------+    +--------+    +--------+
   addr2         addr3         addr4

在这里,每次将字符串附加到链表时,都会分配一个新节点,并将字符串复制到数据部分。请注意,每次分配新节点时,节点的地址都是不同的。

在上面的例子中,数据为“def”的第一个列表具有地址addr1,第二个列表的数据为“def”的节点具有地址 addr3。所以如果你尝试用==运算符比较这两个节点,自然比较结果会是假的,因为相等会比较节点的地址,它们是不同的,因此返回假。

如果要特别匹配节点中的数据,则需要对其进行专门比较。也就是说,访问其中的每个节点list并将数据部分与另一个节点(list1)进行比较。

另一方面,如果您已经确定了特定链表中的节点地址,那么您可以使用该地址进行比较。例如,如果您遍历列表直到最后并获得最后一个带有“ghi”的节点的地址addr4,那么您可以稍后使用此地址比较列表中的特定节点,前提是该节点尚未被释放并使用相同的数据重新创建。在这种情况下,您可以清楚地看到即使该节点内的数据发生更改,地址也将保持不变。

于 2013-08-02T06:11:01.840 回答
2

因为listand llink是节点地址,我们不能有两个不同的节点具有相同的地址,所以它非常简单的技术可以找到llinklist(第一个)开始的位置。

假设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节点组成。

于 2013-08-02T05:46:34.327 回答
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
}
于 2013-08-02T06:13:51.590 回答