[Linux/C/Cprops]LinkList實作

本篇筆記自己使用cprops的linklist api

環境:Linux Ubuntu 14.0.1 (VM 9 workstations)
編譯器:Code Blocks

測試項目如下:

  1. 可否將自定義結構加入
  2. 可否根據不同的key去尋找結構
  3. 尋找方法? (ex:建樹、輪詢)
  4. Insert after,before 的使用

標頭檔:
#include <string.h>
#include <cprops/linked_list.h>

一開始在測試的時候瘋狂失敗,因為在範例中多了一個屬性

COLLECTION_MODE_COPY 

這個屬性的意思是當你新增一個節點時,要不要複製一份資料再新增。可是我們現在用的是位置存取,
如果他複製了一份位置過去,但裡面卻沒有指定到我們賦予值的位置上...那就什麼都沒有啊!

所以還沒刪掉的時候我去查了新增前跟新增後的位置,發現根本完全不一樣,拿掉後就正常了。

  • 可否將自定義結構加入
可以,詳細看程式碼
結構如下:

struct node
{
    int fd;
    char buf[20];
};

  • 可否根據不同的key去尋找結構
範例中,在cp_list_create_list的選項中有一個cp_compare_fn可用來指定自己想要的compare方式,這就是用來做搜尋的func。

預設是strcmp(char *s1,char *s2)
回傳值 return s1>s2 ? 1 : s1==s2 ? 0 : -1;
比對方式是照順序比對字元的大小
ex: strcmp("123","abc");
轉成  {49,50,51},{97,98,99}
因為49<97所以return -1;
ex:strcmp("1ab","123");
轉成  {49,97,98},{49,50,51}
因為49=49,比對第二個
因為97>50所以return 1;

所以我們只要依照這種模式去做出compare函數的model給予linklist就可以了。
這裡使用結構中的buf做搜尋比對
compare實作如下:
int nodecompare(void *p1,void *p2)
{
    cmpCnt++;
    return strcmp(((struct node *)p1)->buf,((struct node *)p2)->buf);
}


  • 尋找方法? (ex:建樹、輪詢)
為了測試api裡面的搜尋方法,定義了一個全域變數cmpCnt去做計數,當我每次進入自定義的compare函式中就+1。
結果發現是輪詢的,但速度很快,測試的10000的樣本查 "10000" 也是秒殺。
但只會拿到第一個符合的資料。

註:若要測試搜尋可將程式碼下方while的註解拿掉即可


  • Insert after,before 的使用

void *cp_list_insert_after(cp_list *list, void *item, void *existing);
void *cp_list_insert_before(cp_list *list, void *item, void *existing);
這兩個方法都是用compare去判斷的,也就是說給予的參考值也要符合。
第一個參數:list位置
第二個參數:要插入的結構
第三個參數:尋找的結構

如果參考的結構找不到或null,after會放在list最後,before會放在最前面

ex:

struct node *cmpinfo= (struct node *)malloc(sizeof(struct node));
strcpy(cmpinfo->buf,"10");

宣告一個結構,並將buf賦予值 "10" 做為參考


完整程式碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <cprops/linked_list.h>

struct node
{
    int fd;
    char buf[20];
};

void print_and_free(void *ptr)
{
    struct node *txt = (struct node *) ptr;

    printf(" -> %s", txt->buf);
    free(txt);
}

int cmpCnt = 0;

int nodecompare(void *p1,void *p2)
{
    cmpCnt++;
    return strcmp(((struct node *)p1)->buf,((struct node *)p2)->buf);
}

int main(int argc, char *argv[])
{
    int i,j;
    char buf[0x20];
    cp_list *l =
        cp_list_create_list(COLLECTION_MODE_MULTIPLE_VALUES,
                            (cp_compare_fn) nodecompare, (cp_copy_fn) strdup, NULL);

    for (i = 1; i <=10; i++)
    {
        for(j =1; j<=10; j++)
        {

            sprintf(buf, "%d", i*j);
            struct node *tmp = (struct node *)malloc(sizeof(struct node));
            tmp->fd = i;
            strcpy(tmp->buf, buf);
            cp_list_append(l, tmp);
        }
    }

    struct node *cmpinfo= (struct node *)malloc(sizeof(struct node));
    strcpy(cmpinfo->buf,"10");

    struct node *tmp = (struct node *)malloc(sizeof(struct node));
    strcpy(tmp->buf, "after 10");
    cp_list_insert_after(l, tmp, cmpinfo);
    
    // Scan Serch
    /*
        while(1)
        {
            char typein[20];
            fgets(typein,20,stdin);
            typein[strlen(typein)-1] = '\0';
            if (typein[0] == '\0') break;

            struct node *txt = (struct node *)malloc(sizeof(struct node));
            strcpy(txt->buf,typein);
    cmpCnt=0;
            txt = cp_list_search(l,txt);
            if(txt==NULL)
                printf("can't find\n");
            else
                printf("(%d,%s)\nSerchNode:%d\n",txt->fd,txt->buf,cmpCnt);
        }*/

    cp_list_destroy_custom(l, print_and_free);

    printf("\n");

    return 0;
}

以上。

沒有留言:

張貼留言