資料結構 鍊錶 雙向通用鍊錶

2022-06-05 05:57:07 字數 3921 閱讀 9181

目錄參考

節點:非通用鍊錶自理解概念:節點攜帶資訊

襪子:掛在到鉤子的東西

通用鍊錶自理解概念:資訊攜帶節點

襪子:擺到晾衣架圓形框的一截上,使得節點成為襪子的乙個成員指標變數

通用鍊錶與非通用鍊錶的區別

通用鍊錶節點被放到資訊結構體中,通過偏移找到所在的結構體(即是通過偏移找到襪子頭)

而非通用鍊錶是在節點中攜帶資訊結構體的指標的(即是節點就攜帶資訊)。

別人通俗理解,讀者不必理會本小點

/*

*structure of a node in a doubly linked list.

*/typedef struct lss_list

lss_list;

typedef struct lss_list listitem_t;

資訊訪問

/*

* @param item current node's pointer.

* @param type structure name of type.

* @param member member name of the doubly linked list in the structure.

*/#define lss_list_entry(item, type, member) \

((type *)((char *)(item) - (unsigned long)(&((type *)0)->member)))

1. 初始化鍊錶
/**

* @brief 鍊錶初始化

* @param pstlist:需要初始化的鍊錶(節點)指標

* @retval none

* @author lzm

*/void listinit(listitem_t *pstlist)

2. 獲取第乙個節點
/**

* @brief 獲取第乙個節點

* @param pstobject:當前節點指標

* @retval none

* @author lzm

*/#define listgetfirst(pstobject) ((pstobject)->pstnext)

3. 插入乙個節點(頭)

/**

* @brief 插入當前節點後面

* @param pstlist:鍊錶(也是當前節點)

* @param pstnode:節點(需要插入的節點)

* @retval none

* @author lzm

*/void listadd(lss_list *pstlist, lss_list *pstnode)

4. 插入乙個節點(尾)
/**

* @brief 插入鍊錶尾部

* @param pstlist:鍊錶(也是當前節點)

* @param pstnode:節點(需要插入的節點)

* @retval none

* @author lzm

*/void listtailinsert(lss_list *pstlist, lss_list *pstnode)

5. 刪除乙個節點

/**

* @brief 刪除當前節點

* @param pstnode:節點(需要刪除的節點)

* @retval none

* @author lzm

*/void listdelete(lss_list *pstnode)

6. 判斷乙個鍊錶是否為空
/**

* @brief 刪除當前節點

* @param pstnode:節點(需要刪除的節點)

* @retval true:鍊錶為空

* @retval false:鍊錶不為空

* @author lzm

*/bool listempty(lss_list *pstnode)

7. 獲取到資訊控制代碼的偏移 *
/**

* @brief 獲取到資訊控制代碼的偏移

* @param type:資訊結構體型別

* @param member:成員名字,即是字段(域)

* @retval 偏移長度(單位:byte)

* @author lzm

*/#define getoffsetofmenber(type, member) ((uint32_t)&(((type *)0)->member))

8. 獲取節點所在的資訊控制代碼 *
/**

* @brief 獲取節點所在的資訊控制代碼

* @param type:資訊結構體型別

* @param member:成員名字,即是字段(域)

* @retval 返回節點所在的資訊控制代碼

* @author lzm

*/#define getitemdatahandle(item, type, member) \

((type *)((char *)item - getoffsetofmenber(type, member))) \

9. 遍歷鍊錶
/**

* @brief 刪除節點並重新初始化

* @param pstlist:需要重新初始化的鍊錶節點

* @retval

* @author lzm

*/#define list_for_each(item, list) \

for ((item) = (list)->pstnext; \

(item) != (list); \

(item) = (item)->pstnext)

10. 遍歷整個鍊錶並獲得資訊控制代碼(巨集) *
/**

* @brief 遍歷整個鍊錶並獲得資訊控制代碼(巨集)

* @param handle:儲存目標節點資訊控制代碼

* @param item:需要遍歷的鍊錶(節點)

* @param type:資訊型別(結構體名)

* @param member:該鍊錶在 type 中的名字

* @retval 就是也該for語句

* @author lzm

*/#define list_for_each_handel(handle, list, type, member) \

for (handle = getitemdatahandle((list)->pstnext, type, member); \

&handle->member != (list); \

handle = getitemdatahandle(handle->member.pstnext, type, member))

11. 刪除節點並重新初始化
void oslistdel(lss_list *pstprevnode, lss_list *pstnextnode)

/*** @brief 刪除節點並重新初始化

* @param pstlist:需要重新初始化的鍊錶節點

* @retval

* @author lzm

*/void listdelinit(lss_list *pstlist)

liteos 核心原始碼

資料結構 鍊錶 雙向鍊錶

注意typedef的定義結構,以及dinklist的資料型別 typedef struct dnode dnode,dinklist 注意插入第乙個結點時,prior指標的空指向問題 if l next null 若l後繼結點為空 則省略該步驟 l next prior p 基本 頭插法建立雙向鍊錶...

資料結構 雙向鍊錶,迴圈鍊錶

也許是自己太小看資料結構,練習了幾天還在第二章徘徊,可自己覺得基礎還是要打牢的好 總結一下 第乙個是雙向鍊錶,include include typedef struct node node,linklist void creat linklist l else int insert linklis...

C實現通用資料結構 雙向鍊錶

雙向鍊錶也叫雙鏈表,是鍊錶的一種,它的每個資料結點中都有兩個指標,分別 指向直接後繼next和直接前驅prev。所以,從雙向鍊錶中的任意乙個結點開始,都可以很方便地訪問它的前驅結點和後繼結點。為了標識鍊錶的頭和尾,將 第乙個元素的prev指標和最後乙個元素的next指標設定為null 要反向遍歷整個...