【 聲明:著作權,歡迎轉載,請勿用於商業用途。 聯絡信箱:feixiaoxing @163.com】
前面的部落格我們介紹了單向鏈表。那麼我們今天介紹的雙向鏈表,顧名思義,就是資料本身具備了左邊和右邊的雙向指標。雙向鏈表相比較單向鏈表,主要有下面幾個特點:
(1)在資料結構中具有雙向指標
(2)插入資料的時候需要考慮前後的方向的操作
(3)同樣,刪除資料的是有也需要考慮前後方向的操作
那麼,一個非迴圈的雙向鏈表操作應該是怎麼樣的呢?我們可以自己嘗試一下:
(1)定義雙向鏈表的基本結構
typedef struct _DOUBLE_LINK_NODE{int data;struct _DOUBLE_LINK_NODE* prev;struct _DOUBLE_LINK_NODE* next;}DOUBLE_LINK_NODE;
(2)建立雙向鏈表節點
DOUBLE_LINK_NODE* create_double_link_node(int value){DOUBLE_LINK_NODE* pDLinkNode = NULL;pDLinkNode = (DOUBLE_LINK_NODE*)malloc(sizeof(DOUBLE_LINK_NODE));assert(NULL != pDLinkNode);memset(pDLinkNode, 0, sizeof(DOUBLE_LINK_NODE));pDLinkNode->data = value;return pDLinkNode;}
(3)刪除雙向鏈表
void delete_all_double_link_node(DOUBLE_LINK_NODE** pDLinkNode){DOUBLE_LINK_NODE* pNode;if(NULL == *pDLinkNode)return ;pNode = *pDLinkNode;*pDLinkNode = pNode->next;free(pNode);delete_all_double_link_node(pDLinkNode);}
(4)在雙向鏈表中尋找資料
DOUBLE_LINK_NODE* find_data_in_double_link(const DOUBLE_LINK_NODE* pDLinkNode, int data){DOUBLE_LINK_NODE* pNode = NULL;if(NULL == pDLinkNode)return NULL;pNode = (DOUBLE_LINK_NODE*)pDLinkNode;while(NULL != pNode){if(data == pNode->data)return pNode;pNode = pNode ->next;}return NULL;}
(5)雙向鏈表中插入資料
STATUS insert_data_into_double_link(DOUBLE_LINK_NODE** ppDLinkNode, int data){DOUBLE_LINK_NODE* pNode;DOUBLE_LINK_NODE* pIndex;if(NULL == ppDLinkNode)return FALSE;if(NULL == *ppDLinkNode){pNode = create_double_link_node(data); assert(NULL != pNode);*ppDLinkNode = pNode;(*ppDLinkNode)->prev = (*ppDLinkNode)->next = NULL;return TRUE;}if(NULL != find_data_in_double_link(*ppDLinkNode, data))return FALSE;pNode = create_double_link_node(data);assert(NULL != pNode);pIndex = *ppDLinkNode;while(NULL != pIndex->next)pIndex = pIndex->next;pNode->prev = pIndex;pNode->next = pIndex->next;pIndex->next = pNode;return TRUE;}
(6)雙向鏈表中刪除資料
STATUS delete_data_from_double_link(DOUBLE_LINK_NODE** ppDLinkNode, int data){DOUBLE_LINK_NODE* pNode;if(NULL == ppDLinkNode || NULL == *ppDLinkNode)return FALSE;pNode = find_data_in_double_link(*ppDLinkNode, data);if(NULL == pNode)return FALSE;if(pNode == *ppDLinkNode){if(NULL == (*ppDLinkNode)->next){*ppDLinkNode = NULL;}else{*ppDLinkNode = pNode->next;(*ppDLinkNode)->prev = NULL;}}else{if(pNode->next) pNode->next->prev = pNode->prev; pNode->prev->next = pNode->next;}free(pNode);return TRUE;}
(7)統計雙向鏈表中資料的個數
int count_number_in_double_link(const DOUBLE_LINK_NODE* pDLinkNode){int count = 0;DOUBLE_LINK_NODE* pNode = (DOUBLE_LINK_NODE*)pDLinkNode;while(NULL != pNode){count ++;pNode = pNode->next;}return count;}
(8)列印雙向鏈表中資料
void print_double_link_node(const DOUBLE_LINK_NODE* pDLinkNode){DOUBLE_LINK_NODE* pNode = (DOUBLE_LINK_NODE*)pDLinkNode;while(NULL != pNode){printf("%d\n", pNode->data);pNode = pNode ->next;}}
注意:
今天我們討論的雙向鏈表是非迴圈的,大家可以考慮一下如果改成迴圈雙向鏈表,應該怎麼寫?如果是有序的迴圈雙向鏈表,又該怎麼寫?
【預告: 下面我們討論的是迴圈單向鏈表】