freertos的節點結構體定義如下:
/* 節點結構體定義 */
struct xlist_item
;typedef struct xlist_item listitem_t; /* 節點資料型別重定義 */
接下來分析,為什麼要定義這樣乙個節點?
ticktype_t xitemvalue; /* 輔助值,用於幫助節點做順序排列 */
// 關於ticktype_t的定義
#if( configuse_16_bit_ticks == 1 )
typedef uint16_t ticktype_t;
#define portmax_delay ( ticktype_t ) 0xffff
#else
typedef uint32_t ticktype_t;
#define portmax_delay ( ticktype_t ) 0xfffffffful
#endif
ticktype_t,顧名思義,就是系統滴答的型別。在stm32中,使用的系統滴答定時器為24位,因此要定義成32位型別(16位不夠用),xitemvalue中儲存的是當前任務需要的延時值。在延時列表中,各任務根據延時大小(xitemvalue值)按公升序排列。
void * pvowner; /* 指向擁有該節點的核心物件,通常是tcb */
儲存當前任務的任務控制塊,可以通過訪問tcb從延時列表中恢復任務至就緒列表。
void * pvcontainer; /* 指向該節點所在的鍊錶 */
通過這個變數,可以知道節點位於就緒列表、延時列表或其他。
如何初始化節點?直接讓 pvcontainer 這個指標為空(null),表示節點沒有插入任何鍊錶。
/* 節點初始化 */
void vlistinitialiseitem(listitem_t *const pxitem)
鍊錶結構體:
/* 鍊錶結構體定義 */
typedef struct xlist
list_t;
分析鍊錶結構體的成員:
ubasetype_t uxnumberofitems; /* 鍊錶節點計數器 */
這個用於記錄當前鍊錶中有多少個任務(計數器)。
listitem_t * pxindex; /* 鍊錶節點索引指標 */
這個每次都能指向當前鍊錶中的下乙個任務(1→2→3...)
minilistitem_t xlistend; /* 鍊錶最後乙個節點 */
指向自身。
接下來是鍊錶的初始化,**看上去非常晦澀難懂,其實所做的工作就是,把索引指標指向最後乙個節點,然後把最後乙個節點的前指標和後指標都指向自身,並將節點計數器清零,表示鍊錶為空(沒有任務)。
/* 鍊錶初始化 */
void vlistinitialise(list_t * const pxlist)
初始化完成後,根節點如下圖所示:
接下來是鍊錶的尾部插入新節點:
在鍊錶初始化後,pxlist->pxindex指向最小mini節點(鍊錶中沒有節點時,mini節點的next和previous均指向自身),而此時如果插入乙個節點1,就會變成mini節點的next指向節點1,而由於是雙向鍊錶,mini節點的previous也指向節點1。同理,節點1的next和previous都指向mini節點。
但pxlist->pxindex->next指向了節點1,pxlist->pxindex->next->next指向節點2...
如果繼續在尾部插入節點2,(先通過pxlist->pxindex獲取mini節點)則節點2的next指向mini節點,而節點2的previous指向節點1,而節點1的next指向節點2,mini節點的previous指向節點2,整體的節點在不斷往右生長,如圖所示:
可以通過pxlist->pxindex來訪問鍊錶中的所有節點,怎麼實現?已經知道的是,pxlist->pxindex指向mini節點,如上圖所示。如果listitem_t * const pxindex = pxlist->pxindex,那麼pxindex的next節點就是節點1(pxindex->next),節點1的next就是節點2(pxindex->next->next),這樣就可以訪問整個鍊錶。
插入節點的**:
/**
* @brief 將節點插入到鍊錶的尾部
* @param pxlist 列表
* @param pxnewlistitem 新列表項
*/void vlistinsertend(list_t * const pxlist, listitem_t * const pxnewlistitem)
刪除節點(用途:將任務從就緒列表中刪除等...)
/* 將節點從鍊錶中刪除 */
ubasetype_t uxlistremove(listitem_t * const pxitemtoremove)
/* 初始化該節點所在的鍊錶為空,表示節點還沒有插入任何鍊錶 */
pxitemtoremove->pvcontainer = null;
/* 鍊錶節點計數器-- */
(pxlist->uxnumberofitems)--;
/* 返回鍊錶中剩餘節點的個數 */
return pxlist->uxnumberofitems;
}
然後在主函式中進行測試
/* main.c */
#include "list.h"
/* 定義根節點 */
struct xlist list_test;
/* 定義3個節點 */
struct xlist_item list_item1;
struct xlist_item list_item2;
struct xlist_item list_item3;
int main(void)
}
測試結果如下:
鍊錶專題 4 鍊錶
鍊錶是一大堆節點合起來連起來組成的表的總稱。其中每個節點中都有指標變數指向列表中的下乙個節點。鍊錶中第乙個節點被稱之為表頭 head 所以將第乙個節點的指標變數命名為head。最後乙個節點並沒有神馬特殊的名字,但是它 最後乙個節點 有一項特殊的屬性 最後乙個節點將null作為最後乙個變數的值 所以檢...
Python (二)列表 元組
一 列表 相當於c中的陣列,內部的元素是可以改變的,對元素進行增刪改以及進行插入操作。是一種有序的集合 建立list list1 test1 test2 test3 訪問元素 通過下標進行索引 list1 2 列表的下標從0開始,在元素的個數減1的位置結束。末尾追加元素 指定位置插入元素 listt...
leetCode 鍊錶專題
sort a linked list in o n log n time using constant space complexity.用歸併排序 其中只是建立了乙個prehead節點 占用空間o 1 時間o nlogn public class solution 常規合併排序思路 listnod...