2013-08-02 56 views
3

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

编辑:由于所有给定的,我的错误,我实际上是在做错误的方式。我必须比较列表的相同实例。

回答

2

因为listllink是节点地址,我们不能有相同地址的两个不同的节点,它非常简单的技术,以找到在list(第一)内llink开始。

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

+0

那么,为什么它返回-1,当他们比较两个环节 –

+0

@ ashish2expert如果没有发现读更新ansed –

+0

你能告诉我,当它返回正值的例子吗? –

2

与头部列表list2

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

当函数分配的节点将分配一个空闲存储位置与所述节点的尺寸,然后分配在节点的数据部分中的字符串(其中它必须分配字符串)。

列表头list

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

这里每次你追加一个字符串的链表,一个新的节点分配和字符串在数据部分复制。请注意,每次分配新节点时,节点的地址都不相同。

在上面第一个带有数据“def”的列表中,地址为addr1,第二个列表中带有数据“def”的节点的地址为addr3。因此,如果您尝试将这两个节点与==运算符进行比较,那么自然比较结果将是错误的,因为相等性将比较不同的节点地址,从而返回错误。

如果要特别匹配节点中的数据,则需要专门对其进行比较。即访问list中的每个节点,并将数据部分与另一个节点(list1)进行比较。另一方面,如果您在特定链接列表中执行了节点地址,则可以使用该地址进行比较。例如,如果遍历列表直到结束,并获取地址为addr4且带有“ghi”的最后一个节点的地址,则可以使用此地址比较列表中的该特定节点,前提是该节点没有被释放并用相同的数据重新创建。在这种情况下,即使该节点内的数据发生更改,地址也会保持不变。

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 
}