數據結構—鏈表詳解


淺談數據結構——鏈表

本篇隨筆就數據結構——鏈表進行講解。鏈表是一種特別實用的數據結構,我把它理解為數組的升級版,也就是在數組的基礎上,它能做到在任意位置添加或者刪除元素,而不影響其他元素。鏈表還是我們進行圖論學習時,圖的常用存儲方式——鄰接表(鏈式前向星)的實現基礎。學習鏈表需要讀者具有一定的語法基礎,最好會一點點指針。(不會也沒關系,我們主要講解數組模擬鏈表)

什么是鏈表

鏈表,顧名思義,就是帶鏈的表。我已經說過,鏈表屬於數組的加強版。那我們可以借助數組來理解鏈表:如果說數組是一長排連在一起的“方塊”的話,那么鏈表就是把這些方塊“拉開“,每個方塊還有兩個箭頭,分別指向這個方塊前面的方塊和后面的方塊。

這樣我們就可以理解,為什么鏈表可以支持隨機插入和刪除了。從某種意義上來說,這里的每一個方塊都是離散的,我們在某兩點插入的時候,只需要把要插入的元素,這個元素目標位置前面的元素、后面的元素的箭頭改一下,就做到了插入的操作。刪除同理。

鏈表的實現原理

根據剛才的理解,我們可以發現,我們可以用一個結構體來模擬每一個方塊,結構體中存一個元素和兩個指針,指針分別指向上一個元素的位置和下一個元素的位置。但是蒟蒻不會指針指針的實現比較麻煩,而且在調試的時候也不是很理想。所以我們來想指針的本質就是告訴你一個位置,那么針對於”加強數組“鏈表來講,這個位置可以用什么來表示呢?

對,數組下標。

所以我們剛才的結構體就可以簡化,變成存一個元素和兩個int變量(存儲數組下標)。這樣,我們就可以用結構體數組模擬鏈表的實現。

鏈表基本操作的代碼實現

鏈表實現的精髓就是更改指針,改掉了三個元素(前,中,后)的指針使鏈表合法,就完成了我們需要做的操作,本部分不再就每段代碼進行過多講解,請大家自行理解代碼含義,最好借助紙筆推演,看的會更明白一些。

(1)初始化

我們初始化鏈表的時候,要根據題目意思處理開頭的第一個元素,這很重要!並且,我們把所有的指針都清成-1,這樣保證了鏈表初始絕對合法。

void init()
{
    for(int i=1;i<=n;i++)
        a[i].pre=a[i].nxt=-1;
    a[1].nxt=-1;
    a[1].pre=0;
    a[0].nxt=1;
}

(2)插入操作

void insert_left(int pos,int k)//把元素k插入到pos元素之前
{
    a[a[pos].pre].nxt=k;
    a[k].pre=a[pos].pre;
    a[pos].pre=k;
    a[k].nxt=pos;
}
void insert_right(int pos,int k)//把元素k插入到pos元素之后
{
    a[a[pos].nxt].pre=k;
    a[k].nxt=a[pos].nxt;
    a[pos].nxt=k;
    a[k].pre=pos;
}

(3)刪除操作

void remove(int x)
{
    if(a[x].pre==-1)
        return;
    a[a[x].pre].nxt=a[x].nxt;
    a[a[x].nxt].pre=a[x].pre;
    a[x].pre=-1;
    a[x].nxt=-1;
}

(4)遍歷

void print()
{
    int start=a[0].nxt;
    while(1)
    {
        printf("%d ",start);
        if(a[start].nxt==-1)
            break;
        start=a[start].nxt;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM