您好,登錄后才能下訂單哦!
本篇內容介紹了“tbox鏈表list和list_entry的使用方法”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
TBOX中提供了各種列表操作:
list: 元素在內部維護的雙向鏈表
list_entry: 元素在外部維護的雙向鏈表
single_list: 元素在內部維護的單向鏈表
single_list_entry: 元素在外部維護的單向鏈表
由于雙鏈和單鏈的接口使用類似,這里主要就講解雙鏈的具體使用。
那什么是內部維護和外部維護呢? 簡單地說:
外部維護:就是鏈表容器本身不存儲元素,不開辟內存空間,僅僅是一個節點頭,這樣比較節省內存,更加靈活。(尤其是在多個鏈表間元素遷移的時候,或者多個鏈表需要統一內存池維護的時候)。
內部維護:就是鏈表容器本身回去開辟一塊空間,去單獨存儲元素內容,這種方式對接口的操作比較簡單,但是靈活性和性能不如前一種,如果不需要多個鏈表維護同一種元素,那么使用這種模式簡單操作下,更為妥當。(而且內部元素的存儲也是用內存池優化過的)。
list的使用很簡單,接口用起來也很方便,這里給個簡單的例子:
// 創建一個long類型的雙鏈,參數0表示采用默認的自動元素增長大小,也可以手動設置更適合的大小 tb_list_ref_t list = tb_list_init(0, tb_element_long()); if (list) { // 在鏈表頭部插入元素:1,并返回這個新元素的迭代器索引 tb_size_t itor = tb_list_insert_head(list, (tb_pointer_t)1); // 在之前新的元素后面插入一個新元素:2 tb_list_insert_next(list, itor, (tb_pointer_t)2); // 在鏈表尾部插入元素:3 tb_list_insert_tail(list, (tb_pointer_t)3); // 移除指定的元素 tb_list_remove(list, itor); // 遍歷所有鏈表元素, tb_for_all(tb_long_t, item, list) { // 打印元素值 tb_trace_i("%ld", item); } // 銷毀list tb_list_exit(list); }
list_entry由于是外置式的容器,需要在外面自己定義的結構體上進行操作,例如定義:
// 鏈表元素結構體 typedef struct __tb_demo_entry_t { // 外置雙鏈的節點,用于鏈表維護 tb_list_entry_t entry; // 元素的實際數據 tb_size_t data; }tb_demo_entry_t;
對鏈表的具體操作如下:
// 定義一些靜態元素,用于插入鏈表(實際使用可能需要自己動態創建他們) tb_demo_entry_t entries[12] = { { {0}, 0 } , { {0}, 1 } , { {0}, 2 } , { {0}, 3 } , { {0}, 4 } , { {0}, 5 } , { {0}, 6 } , { {0}, 7 } , { {0}, 8 } , { {0}, 9 } , { {0}, 10} , { {0}, 11} }; // 初始化鏈表,需要指定外置元素的結構體類型,鏈表的節點名字 tb_list_entry_head_t list; tb_list_entry_init(&list, tb_demo_entry_t, entry, tb_null); // 插入一些元素,注意:所有操作都是在外置結構體中的list_entry節點上操作 tb_list_entry_insert_tail(&list, &entries[5].entry); tb_list_entry_insert_tail(&list, &entries[6].entry); tb_list_entry_insert_tail(&list, &entries[7].entry); tb_list_entry_insert_tail(&list, &entries[8].entry); tb_list_entry_insert_tail(&list, &entries[9].entry); tb_list_entry_insert_head(&list, &entries[4].entry); tb_list_entry_insert_head(&list, &entries[3].entry); tb_list_entry_insert_head(&list, &entries[2].entry); tb_list_entry_insert_head(&list, &entries[1].entry); tb_list_entry_insert_head(&list, &entries[0].entry); // 訪問具體某個節點的元素數據 tb_demo_entry_t* entry = (tb_demo_entry_t*)tb_list_entry(&list, &entries[5].entry); tb_trace_i("entry: %lu", entry->data); // 遍歷所有元素 tb_trace_i("insert: %lu", tb_list_entry_size(&list)); tb_for_all_if(tb_demo_entry_t*, item0, tb_list_entry_itor(&list), item0) { tb_trace_i("%lu", item0->data); } // 替換頭尾的元素 tb_list_entry_replace_head(&list, &entries[10].entry); tb_list_entry_replace_last(&list, &entries[11].entry); // 移除頭尾的元素 tb_list_entry_remove_head(&list); tb_list_entry_remove_last(&list); // 移動元素位置,這里吧頭尾的元素對調了下 tb_list_entry_ref_t head = tb_list_entry_head(&list); tb_list_entry_moveto_head(&list, tb_list_entry_last(&list)); tb_list_entry_moveto_tail(&list, head); // 退出列表 tb_list_entry_exit(&list);
怎么樣,也不是很復雜吧,由于元素的內存都在外面自己維護,所以靈活性提升了不少,并且可以多個鏈表同時維護,然后共用一個內存池進行優化,效率和內存都能得到最大的提升,這種模式在linux內核里面很常見。
如果要做比喻的話,list就是傻瓜式操作,list_entry就是定制化操作。。。
“tbox鏈表list和list_entry的使用方法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。