双向链表数据结构
文章目錄
- 1 雙向鏈表數據結構
- 1.1 鏈表結構定義
- 1.2 鏈表操作實現
1 雙向鏈表數據結構
1.1 鏈表結構定義
對于雙向鏈表的通常做法:
我們可以使用更好的方案:
思考一個問題:已知父結構,如何訪問特定結點?
1.2 鏈表操作實現
鏈表的定義如下:
#ifndef TLIB_H #define TLIB_H// 標準頭文件,里面包含了常用的類型定義,如uint32_t #include <stdint.h> // tinyOS鏈表的結點類型 typedef struct _tNode {// 該結點的前一個結點struct _tNode * preNode;// 該結點的后一個結點struct _tNode * nextNode; }tNode;/********************************************************************************************************** ** Function name : tNodeInit ** Descriptions : 初始化結點類型 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tNodeInit (tNode * node);// tinyOS鏈表類型 typedef struct _tList { // 該鏈表的頭結點tNode headNode;// 該鏈表中所有結點數量uint32_t nodeCount; }tList;/********************************************************************************************************** ** Function name : tNodeParent ** Descriptions : 獲取結點所在的父struct結構首地址 ** parameters : 無 ** Returned value : 父struct結構首地址 ***********************************************************************************************************/ #define tNodeParent(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name)/********************************************************************************************************** ** Function name : tListInit ** Descriptions : 鏈表初始化 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tListInit (tList * list);/********************************************************************************************************** ** Function name : tListCount ** Descriptions : 返回鏈表中結點的數量 ** parameters : 無 ** Returned value : 結點數量 ***********************************************************************************************************/ uint32_t tListCount (tList * list);/********************************************************************************************************** ** Function name : tListFirst ** Descriptions : 返回鏈表的首個結點 ** parameters : list 查詢的鏈表 ** Returned value : 首個結點,如果鏈表為空,則返回0 ***********************************************************************************************************/ tNode * tListFirst (tList * list);/********************************************************************************************************** ** Function name : tListLast ** Descriptions : 返回鏈表的最后一個結點 ** parameters : list 查詢的鏈表 ** Returned value : 最后的結點,如果鏈表為空,則返回0 ***********************************************************************************************************/ tNode * tListLast (tList * list);/********************************************************************************************************** ** Function name : tListPre ** Descriptions : 返回鏈表中指定結點的前一結點 ** parameters : list 查詢的鏈表 ** parameters : node 參考結點 ** Returned value : 前一結點結點,如果結點沒有前結點(鏈表為空),則返回0 ***********************************************************************************************************/ tNode * tListPre (tList * list, tNode * node);/********************************************************************************************************** ** Function name : tListNext ** Descriptions : 返回鏈表中指定結點的后一結點 ** parameters : list 查詢的鏈表 ** parameters : node 參考結點 ** Returned value : 后一結點結點,如果結點沒有前結點(鏈表為空),則返回0 ***********************************************************************************************************/ tNode * tListNext (tList * list, tNode * node);/********************************************************************************************************** ** Function name : tListRemoveAll ** Descriptions : 移除鏈表中的所有結點 ** parameters : list 待清空的鏈表 ** Returned value : 無 ***********************************************************************************************************/ void tListRemoveAll (tList * list);/********************************************************************************************************** ** Function name : tListAddFirst ** Descriptions : 將指定結點添加到鏈表的頭部 ** parameters : list 待插入鏈表 ** parameters : node 待插入的結點 ** Returned value : 無 ***********************************************************************************************************/ void tListAddFirst (tList * list, tNode * node);/********************************************************************************************************** ** Function name : tListAddLast ** Descriptions : 將指定結點添加到鏈表的末尾 ** parameters : list 待插入鏈表 ** parameters : node 待插入的結點 ** Returned value : 無 ***********************************************************************************************************/ void tListAddLast (tList * list, tNode * node);/********************************************************************************************************** ** Function name : tListRemoveFirst ** Descriptions : 移除鏈表中的第1個結點 ** parameters : list 待移除鏈表 ** Returned value : 如果鏈表為空,返回0,否則的話,返回第1個結點 ***********************************************************************************************************/ tNode * tListRemoveFirst (tList * list);/********************************************************************************************************** ** Function name : tListInsertAfter ** Descriptions : 將指定的結點插入到某個結點后面 ** parameters : list 待插入的鏈表 ** parameters : nodeAfter 參考結點 ** parameters : nodeToInsert 待插入的結構 ** Returned value : 無 ***********************************************************************************************************/ void tListInsertAfter (tList * list, tNode * nodeAfter, tNode * nodeToInsert);/********************************************************************************************************** ** Function name : tListRemove ** Descriptions : 將指定結點從鏈表中移除 ** parameters : list 待移除的鏈表 ** parameters : node 待移除的結點 ** Returned value : 無 ***********************************************************************************************************/ void tListRemove (tList * list, tNode * node);#endif /* TLIB_H */鏈表相關的操作實現如下:
/*************************************** Copyright (c)****************************************************** ** File name : tList.c ** Latest modified Date : 2016-06-01 ** Latest Version : 0.1 ** Descriptions : tinyOS所用的雙向鏈表數據結構。 ** **-------------------------------------------------------------------------------------------------------- ** Created by : 01課堂 lishutong ** Created date : 2016-06-01 ** Version : 1.0 ** Descriptions : The original version ** **-------------------------------------------------------------------------------------------------------- ** Copyright : 版權所有,禁止用于商業用途 ** Author Blog : http://ilishutong.com **********************************************************************************************************/ #include "tLib.h"/********************************************************************************************************** ** Function name : tNodeInit ** Descriptions : 初始化結點類型 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tNodeInit (tNode * node) {node->nextNode = node;node->preNode = node; }// 以下是簡化代碼編寫添加的宏 #define firstNode headNode.nextNode #define lastNode headNode.preNode/********************************************************************************************************** ** Function name : tListInit ** Descriptions : 鏈表初始化 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tListInit (tList * list) {list->firstNode = &(list->headNode);list->lastNode = &(list->headNode);list->nodeCount = 0; }/********************************************************************************************************** ** Function name : tListCount ** Descriptions : 返回鏈表中結點的數量 ** parameters : 無 ** Returned value : 結點數量 ***********************************************************************************************************/ uint32_t tListCount (tList * list) {return list->nodeCount; }/********************************************************************************************************** ** Function name : tListFirst ** Descriptions : 返回鏈表的首個結點 ** parameters : list 查詢的鏈表 ** Returned value : 首個結點,如果鏈表為空,則返回0 ***********************************************************************************************************/ tNode * tListFirst (tList * list) {tNode * node = (tNode *)0;if (list->nodeCount != 0) {node = list->firstNode;} return node; }/********************************************************************************************************** ** Function name : tListLast ** Descriptions : 返回鏈表的最后一個結點 ** parameters : list 查詢的鏈表 ** Returned value : 最后的結點,如果鏈表為空,則返回0 ***********************************************************************************************************/ tNode * tListLast (tList * list) {tNode * node = (tNode *)0;if (list->nodeCount != 0) {node = list->lastNode;} return node; }/********************************************************************************************************** ** Function name : tListPre ** Descriptions : 返回鏈表中指定結點的前一結點 ** parameters : list 查詢的鏈表 ** parameters : node 參考結點 ** Returned value : 前一結點結點,如果結點沒有前結點(鏈表為空),則返回0 ***********************************************************************************************************/ tNode * tListPre (tList * list, tNode * node) {if (node->preNode == node) {return (tNode *)0;} else {return node->preNode;} }/********************************************************************************************************** ** Function name : tListnextNode ** Descriptions : 返回鏈表中指定結點的后一結點 ** parameters : list 查詢的鏈表 ** parameters : node 參考結點 ** Returned value : 后一結點結點,如果結點沒有前結點(鏈表為空),則返回0 ***********************************************************************************************************/ tNode * tListNext (tList * list, tNode * node) {if (node->nextNode == node) {return (tNode *)0;}else {return node->nextNode;} }/********************************************************************************************************** ** Function name : tListRemoveAll ** Descriptions : 移除鏈表中的所有結點 ** parameters : list 待清空的鏈表 ** Returned value : 無 ***********************************************************************************************************/ void tListRemoveAll (tList * list) {uint32_t count;tNode * nextNode;// 遍歷所有的結點nextNode = list->firstNode;for (count = list->nodeCount; count != 0; count-- ){// 先紀錄下當前結點,和下一個結點// 必須紀錄下一結點位置,因為在后面的代碼中當前結點的next會被重置tNode * currentNode = nextNode;nextNode = nextNode->nextNode;// 重置結點自己的信息currentNode->nextNode = currentNode;currentNode->preNode = currentNode;}list->firstNode = &(list->headNode);list->lastNode = &(list->headNode);list->nodeCount = 0; }/********************************************************************************************************** ** Function name : tListAddFirst ** Descriptions : 將指定結點添加到鏈表的頭部 ** parameters : list 待插入鏈表 ** parameters : node 待插入的結點 ** Returned value : 無 ***********************************************************************************************************/ void tListAddFirst (tList * list, tNode * node) {node->preNode = list->firstNode->preNode;node->nextNode = list->firstNode;list->firstNode->preNode = node;list->firstNode = node;list->nodeCount++; }/********************************************************************************************************** ** Function name : tListAddLast ** Descriptions : 將指定結點添加到鏈表的末尾 ** parameters : list 待插入鏈表 ** parameters : node 待插入的結點 ** Returned value : 無 ***********************************************************************************************************/ void tListAddLast (tList * list, tNode * node) {node->nextNode = &(list->headNode);node->preNode = list->lastNode;list->lastNode->nextNode = node;list->lastNode = node;list->nodeCount++; }/********************************************************************************************************** ** Function name : tListRemoveFirst ** Descriptions : 移除鏈表中的第1個結點 ** parameters : list 待移除鏈表 ** Returned value : 如果鏈表為空,返回0,否則的話,返回第1個結點 ***********************************************************************************************************/ tNode * tListRemoveFirst (tList * list) {tNode * node = (tNode *)0;if( list->nodeCount != 0 ){node = list->firstNode;node->nextNode->preNode = &(list->headNode);list->firstNode = node->nextNode;list->nodeCount--;}return node; }/********************************************************************************************************** ** Function name : tListInsertAfter ** Descriptions : 將指定的結點插入到某個結點后面 ** parameters : list 待插入的鏈表 ** parameters : nodeAfter 參考結點 ** parameters : nodeToInsert 待插入的結構 ** Returned value : 無 ***********************************************************************************************************/ void tListInsertAfter (tList * list, tNode * nodeAfter, tNode * nodeToInsert) {nodeToInsert->preNode = nodeAfter;nodeToInsert->nextNode = nodeAfter->nextNode;nodeAfter->nextNode->preNode = nodeToInsert;nodeAfter->nextNode = nodeToInsert;list->nodeCount++; }/********************************************************************************************************** ** Function name : tListRemove ** Descriptions : 將指定結點從鏈表中移除 ** parameters : list 待移除的鏈表 ** parameters : node 待移除的結點 ** Returned value : 無 ***********************************************************************************************************/ void tListRemove (tList * list, tNode * node) {node->preNode->nextNode = node->nextNode;node->nextNode->preNode = node->preNode;list->nodeCount--; }參考資料:
總結
- 上一篇: 汽车交强险收费标准
- 下一篇: 日常生活中省钱的方法 多攒钱从点滴做