rt thread隨筆4補充 雙向鍊錶

2021-09-29 13:53:04 字數 3840 閱讀 2452

typedef

struct dnode

dnode,

*doublelist;

1

struct rt_list_node 2;

6typedef

struct rt_list_node rt_list_t;

rt_list_t 型別的節點裡面有兩個 rt_list_t 型別的節點指標 next 和 prev,分別用來指向鍊錶中的下乙個節點和上乙個節點。

由 rt_list_t 型別的節點構成的雙向煉表示意圖具體見圖

此圖讓我瞬間明白,我之前思考的雙向鍊錶都是錯的

(下圖是乙個雙向鍊錶的插入示意圖),只要看上面的定義

一、 初始化鍊錶節點

rt_list_t 型別的節點的初始化,就是將節點裡面的 next 和 prev 這兩個節點指標指向節點本身

例子:初始化完成後可檢查下鍊錶初始化是否成功?即判斷鍊錶是不是空的就行了,因為初始化完成的時候,鍊錶肯定是空的,注意,在初始化鍊錶的時候其實鍊錶就是煉表頭,需要申請記憶體

1 head =

rt_malloc

(sizeof

(rt_list_t));

/* 申請動態記憶體 */2if

(rt_null == head)

/* 沒有申請成功 */

3rt_kprintf

("動態記憶體申請失敗!\n");

4else

5rt_kprintf

("動態記憶體申請成功,頭結點位址為%d!\n"

,head);6

7rt_kprintf

("\n 雙向鍊錶初始化中......\n");

8rt_list_init

(head);9

if(rt_list_isempty

(head))10

rt_kprintf

("雙向鍊錶初始化成功!\n\n"

);

二、在雙向煉表表頭後面插入乙個節點 :

處理分為 4 步:

1

/* 在雙向鍊錶頭部插入乙個節點 */

2 rt_inline void

rt_list_insert_after

(rt_list_t *l, rt_list_t *n)

3

將要插入的節點設為n,插入位置之前的的位址設定為l,其原來l的後乙個節點為l->next。

剛剛開始看這塊有點懵,通過過程示意圖,加上自己畫圖處理,清楚很多。詳細介紹自己的理解:

第一步:先將l原來的後乙個節點為l->next的prev 改為指向n的鍊錶:l->next->prev=n;

第二步:將n的next變為原先的l指向->next。(先將舊的替換,才能換新的)。

第三步:將新的l的next指向n

第四步:將n的prev指向l

三、在雙向煉表表頭前面插入乙個節點 ||在雙向鍊錶尾部插入乙個節點

分為四步

1 rt_inline void

rt_list_insert_before

(rt_list_t *l, rt_list_t *n)

2

設定:將列表頭為l,l前乙個節點為l->prev,新加入節點為n。

第一步:先將前乙個節點為l->prev的next指向n

第二步:將n的prev 等於原先l->prev的被指向。(先將l原先由頭指向尾的prev先替換給n)

第三步:原先指向l的prev已經給n了,所以更新l的prev指向——將l的prev指向n

第四步:將n的next指向l。

例子:

1

/* 插入節點:順序插入與從末尾插入 */23

rt_kprintf

("新增節點和尾節點新增......\n");

45/* 動態申請第乙個結點的記憶體 */

6 node1 =

rt_malloc

(sizeof

(rt_list_t));

78/* 動態申請第二個結點的記憶體 */

9 node2 =

rt_malloc

(sizeof

(rt_list_t));

1011

rt_kprintf

("新增第乙個節點與第二個節點.....\n");

1213

/* 因為這是在某個節點後面新增乙個節點函式

14 為後面的 rt_list_insert_before(某個節點之前)

15 新增節點做鋪墊,兩個函式新增完之後的順序是

16 head -> node1 -> node2 */

1718

rt_list_insert_after

(head,node2);19

20rt_list_insert_before

(node2,node1);21

22if

((node1->prev == head)

&&(node2->prev == node1))23

rt_kprintf

("新增節點成功!\n\n");

24else

25rt_kprintf

("新增節點失敗!\n\n"

);

四、從雙向鍊錶刪除乙個節點

分為三步:

1 rt_inline void

rt_list_remove

(rt_list_t *n)

2

要注意的是:將要刪除的節點命名為n,那n的前乙個結點為n->prev ,後乙個節點為n->next

第一步:因為要刪除n,所以要將n的prev和next更新,重新定向。將n下乙個節點(n->next)的prev設為n原來指向的prev…

第二步:將n的前乙個結點(n->prev)的next指向n的next

第三步:將刪除的n的prev和next都指向自己n

例子:

1

rt_kprintf

("刪除節點......\n");

/* 刪除已有節點 */

2rt_list_remove

(node1);3

rt_free

(node1)

;/* 釋放第乙個節點的記憶體 */4if

(node2->prev == head)

5rt_kprintf

("刪除節點成功\n\n"

);

RT Thread 雙向鍊錶分析

從鍊錶刪除節點函式 rt list remove 鍊錶節點元素訪問 雙向鍊錶也叫雙鏈表,是鍊錶的一種,是在作業系統中常用的資料結構,它的每個資料結點中都有兩個指標,分別指向直接後繼和直接前驅,其頭指標 head 是唯一確定的。所以,從雙向鍊錶中的任意乙個結點開始,都可以很方便地訪問它的前驅結點和後繼...

Rt Thread之雙向鍊錶學習

struct rt list node typedef struct rt list node rt list t 第一步 看的時候主要是看原來的圖 l next 就是node2,因為要新插入乙個,node2往後退 所以l next prev 就指向新插入的節點。node2的前乙個是n 第二步 原來...

數論隨筆(待補充)

只列舉了做題中用到過的一些數學定理,先暫時整理一部分。1 求n的位數 log10 n 2 n為質數 a m a m n 1 mod n 3 尤拉函式 小於等於n的數中,與n互質的數的數目。euler函式表達通式 euler x x 1 1 p1 1 1 p2 1 1 p3 1 1 p4 1 1 pn...