FreeRTOS專題二 列表(鍊錶)

2021-09-26 05:35:03 字數 3588 閱讀 5292

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...