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