2

GLib ライブラリは、2 つの単一リンク リスト ノードを比較するために次のように実行されます。

 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 内の特定の要素の位置を取得すると書かれています)、ノードまたはリストに含まれるデータですか?

編集:与えられたすべてのおかげで、私の間違いは実際に間違った方法で行っていました。リストの同じインスタンスを比較する必要があります。

4

3 に答える 3

2

頭付きリストlist2

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

関数がノードを割り当てると、ノードのサイズで空きメモリの場所が割り当てられ、ノードのデータ部分 (文字列を割り当てる必要がある場所) に文字列が割り当てられます。

頭付きリストlist

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

ここでは、連結リストに文字列を追加するたびに、新しいノードが割り当てられ、文字列がデータ部分にコピーされます。新しいノードが割り当てられるたびに、ノードのアドレスが異なることに注意してください。

上記の場合、データ "def" を持つ最初のリストには address がaddr1あり、2 番目のリストにはデータ "def" を持つノードがあり、 address があります addr3。したがって、これら 2 つのノードを==演算子で比較しようとすると、当然、比較結果は false になります。これは、同等性が異なるノードのアドレスを比較し、false を返すためです。

ノード内のデータを特に一致させたい場合は、具体的に比較する必要があります。つまり、 の各ノードにアクセスlistし、データ部分を他のノードと比較します ( list1)。

一方、特定のリンク リスト内のノード アドレスを取得した場合は、そのアドレスを使用して比較できます。たとえば、リストを最後までトラバースし、 address を持つ「ghi」を含む最後のノードのアドレスを取得した場合、addr4このアドレスを使用して、リスト内の特定のノードを後で比較できます。解放され、同じデータで再作成されます。このような場合、このノード内のデータが変更されても、アドレスは同じままです。

于 2013-08-02T06:11:01.840 に答える
2

listllinkはノード アドレスであり、同じアドレスを持つ 2 つの異なるノードを持つことはできないため、(first) 内のどこから開始するかを見つける非常に簡単な手法ですllinklist

関数listへのパスが次のようなものであるとします。

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

addresses are assumption 

llink値がの場合、 は の3 番目のノードであるため18、関数は戻ります。2llinklist

llink見つからない場合は を返します-1

(配列インデックスが関数カウント番号で始まるよう0に、リスト内のノード from 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 に答える