前面的博客中,咱們曾經有一篇專門講到單向鏈表的內容。那麼今天討論的鏈表和上次討論的鏈表有什麼不一樣呢?重點就在這個"循環"上面。有了循環,意味着咱們能夠從任何一個鏈表節點開始工做,能夠把root定在任何鏈表節點上面,能夠從任意一個鏈表節點訪問數據,這就是循環的優點。node
那麼在實現過程當中,循環單向鏈表有什麼不一樣?函數
1)打印鏈表數據spa
- void print_data(const LINK_NODE* pLinkNode)
- {
- LINK_NODE* pIndex = NULL;
- if(NULL == pLinkNode)
- return;
-
- printf("%d\n", pLinkNode->data);
- pIndex = pLinkNode->next;
- while(pLinkNode != pIndex){
- printf("%d\n", pIndex->data);
- pIndex = pIndex ->next;
- }
- }
以往,咱們發現打印數據的結束都是判斷指針是否爲NULL,這裏由於是循環鏈表因此發生了變化。原來的條件(NULL != pLinkNode)也修改爲了這裏的(pLinkNode != pIndex)。一樣須要修改的函數還有find函數、count統計函數。.net
2)插入數據指針
- STATUS insert_data(LINK_NODE** ppLinkNode, int data)
- {
- LINK_NODE* pNode;
- if(NULL == ppLinkNode)
- return FALSE;
-
- if(NULL == *ppLinkNode){
- pNode = create_link_node(data);
- assert(NULL != pNode);
-
- pNode->next = pNode;
- *ppLinkNode = pNode;
- return TRUE;
- }
-
- if(NULL != find_data(*ppLinkNode, data))
- return FALSE;
-
- pNode = create_link_node(data);
- assert(NULL != pNode);
-
- pNode->next = (*ppLinkNode)->next;
- (*ppLinkNode)->next = pNode;
- return TRUE;
- }
這裏的insert函數在兩個地方發生了變化:blog
a)若是原來鏈表中沒有節點,那麼鏈表節點須要本身指向本身get
b)若是鏈表節點原來存在,那麼只須要在當前的鏈表節點後面添加一個數據,同時修改兩個方向的指針便可博客
3) 刪除數據string
- STATUS delete_data(LINK_NODE** ppLinkNode, int data)
- {
- LINK_NODE* pIndex = NULL;
- LINK_NODE* prev = NULL;
- if(NULL == ppLinkNode || NULL == *ppLinkNode)
- return FALSE;
-
- pIndex = find_data(*ppLinkNode, data);
- if(NULL == pIndex)
- return FALSE;
-
- if(pIndex == *ppLinkNode){
- if(pIndex == pIndex->next){
- *ppLinkNode = NULL;
- }else{
- prev = pIndex->next;
- while(pIndex != prev->next)
- prev = prev->next;
-
- prev->next = pIndex->next;
- *ppLinkNode = pIndex->next;
- }
- }else{
- prev = pIndex->next;
- while(pIndex != prev->next)
- prev = prev->next;
- prev->next = pIndex->next;
- }
-
- free(pIndex);
- return TRUE;
- }
和添加數據同樣,刪除數據也要在兩個方面作出改變:class
a)若是當前鏈表節點中只剩下一個數據的時候,刪除後須要設置爲NULL
b)刪除數據的時候首先須要當前數據的前一個數據,這個時候就能夠從當前刪除的數據開始進行遍歷
c) 刪除的時候須要重點判斷刪除的數據是否是鏈表的頭結點數據
轉自:http://blog.csdn.net/feixiaoxing/article/details/6853455