在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ 數(shù)據(jù)分析&挖掘/ 循環(huán)單向鏈表
hash表
單詞統(tǒng)計(jì)
鏈表排序
查找
可變參數(shù)
爬樓梯
內(nèi)存
prim算法 中
線性結(jié)構(gòu)的處理
數(shù)據(jù)選擇
prim算法 上
循環(huán)單向鏈表
基數(shù)排序
堆排序
鏈表重合
排序二叉樹(shù)的保存和加載
圖添加和刪除
排序二叉樹(shù)線索化
非遞歸排序
字符串查找 下篇
鏈表逆轉(zhuǎn)
函數(shù)堆棧顯示
遞歸和堆棧
二叉樹(shù)深度遍歷
線性隊(duì)列
循環(huán)和遞歸
快速排序
尋找丟失的數(shù)
A*算法
克魯斯卡爾算法 下
排序二叉樹(shù)
大數(shù)計(jì)算
二叉樹(shù)廣度遍歷
prim算法 下
洗牌算法
圖結(jié)構(gòu)
最大公約數(shù)、最小公倍數(shù)
圖創(chuàng)建
雙向鏈表
字符串查找 上篇
尋路
通用算法的編寫(xiě)
哈夫曼樹(shù) 下
線性堆棧
八皇后
排序二叉樹(shù)刪除-1
挑選最大的n個(gè)數(shù)
字符串查找 中篇
哈夫曼樹(shù) 上
合并排序
回?cái)?shù)
選擇排序
哈希二叉樹(shù)
通用數(shù)據(jù)結(jié)構(gòu)
“數(shù)星星”
單向鏈表
排序二叉樹(shù)插入
圖的保存
排序二叉樹(shù)刪除-2
排序二叉樹(shù)刪除-3
n!中末尾零的個(gè)數(shù)統(tǒng)計(jì)

循環(huán)單向鏈表

前面的博客中,我們?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ù)