如何比较链表节点?

时间:2013-08-02 05:41:59

标签: c linked-list

像这样做的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中给定元素的位置),一个节点或列表中包含的数据?

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

3 个答案:

答案 0 :(得分:2)

由于listllink是节点地址,我们不能拥有两个具有相同地址的不同节点,因此找到llinklist内开始的非常简单的技术}(第一)。

假设list传递给函数就像:

  //     0     1    2   3    4   
list---->[]-->[]-->[]-->[]-->[]---null
         23   42   18  102  324      

addresses are assumption 

如果llink值为18,则函数返回2,因为llinklist中的第三个节点。

如果找不到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
}