前面的博客中,我們曾經(jīng)有一篇專門講到單向鏈表的內(nèi)容。那么今天討論的鏈表和上次討論的鏈表有什么不同呢?重點就在這個"循環(huán)"上面。有了循環(huán),意味著我們可以從任何一個鏈表節(jié)點開始工作,可以把root定在任何鏈表節(jié)點上面,可以從任意一個鏈表節(jié)點訪問數(shù)據(jù),這就是循環(huán)的優(yōu)勢。
那么在實現(xiàn)過程中,循環(huán)單向鏈表有什么不同?
1)打印鏈表數(shù)據(jù)
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;
}
}
以往,我們發(fā)現(xiàn)打印數(shù)據(jù)的結(jié)束都是判斷指針是否為NULL,這里因為是循環(huán)鏈表所以發(fā)生了變化。原來的條件(NULL != pLinkNode)也修改成了這里的(pLinkNode != pIndex)。同樣需要修改的函數(shù)還有find函數(shù)、count統(tǒng)計函數(shù)。
2)插入數(shù)據(jù)
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函數(shù)在兩個地方發(fā)生了變化:
a)如果原來鏈表中沒有節(jié)點,那么鏈表節(jié)點需要自己指向自己
b)如果鏈表節(jié)點原來存在,那么只需要在當(dāng)前的鏈表節(jié)點后面添加一個數(shù)據(jù),同時修改兩個方向的指針即可
3) 刪除數(shù)據(jù)
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;
}
和添加數(shù)據(jù)一樣,刪除數(shù)據(jù)也要在兩個方面做出改變:
a)如果當(dāng)前鏈表節(jié)點中只剩下一個數(shù)據(jù)的時候,刪除后需要設(shè)置為NULL
b)刪除數(shù)據(jù)的時候首先需要當(dāng)前數(shù)據(jù)的前一個數(shù)據(jù),這個時候就可以從當(dāng)前刪除的數(shù)據(jù)開始進(jìn)行遍歷
c) 刪除的時候需要重點判斷刪除的數(shù)據(jù)是不是鏈表的頭結(jié)點數(shù)據(jù)