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