最通俗易懂的鏈表講解

我先來帶你認識一下什麼是鏈表:

鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱爲結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。 相比於線性表順序結構,操作複雜。由於不必須按順序存儲,鏈表在插入的時候可以達到O(1)的複雜度,比另一種線性表順序錶快得多,但是查找一個節點或者訪問特定編號的節點則需要O(n)的時間,而線性表和順序表相應的時間複雜度分別是O(logn)和O(1)。
在這裏插入圖片描述
看完上面這段話,是不是覺得這十幾年的教育都白學了。明明每個字都認識,但是爲什麼連在一起就看不懂了呢?

簡單來說:
鏈表就是不再按照順序來連接了,鏈表的開始是由頭指針開始的,頭指針指向第一個節點或者頭結點。每個結點都有兩部分組成:一個數據域用來存儲你這個元素的數據,一個指針域用來存儲下一個數據的位置,這個是不是感覺有點像港片裏面的線人?一旦你的直屬上司掛掉了,你就變成gu兒了? 同理,如果你的指針域沒有指向下一個結點的話(最後一個結點的指針域都是指向“NULL”的)。那麼就代表這個鏈表已經結束了。


瞭解了鏈表的基礎,那麼現在我們就來看看鏈表的數據結構:

//數據結構
typedef struct monster{
      int id;      //編號
      char *name;  //名稱
        
      //指向下一結點的指針
      struct monster *pNext;
}Monster;

光看結構是看不出什麼來的,所以還是要大家來實戰一下來加強印象:

//示例
typedef struct Monster{
    int id;
    char *name;
    struct Monter *next;   //指向下個結點的指針
}Monster;

void test()
{
    Monster monster1 = {1, "喬布斯"};
   Monster monster2 = {2, "比爾·蓋茨"};
   Monster monster3 = {3, "巴菲特"};
   
   //monster1 就是頭指針
   monster1.next = &monster2;
   monster2.next = &monster3;
   monster3.next = NULL;
}

這裏再給大家講講頭指針和頭結點的基本概念:

頭指針:鏈表中的第一個結點的存儲位置;
頭結點:在單鏈表的第一個結點前附設的一個結點。

兩者的異同點

頭指針 頭結點
若鏈表有頭結點,則是指向頭結點的指針;若沒有則是鏈表指向第一個結點的指針; 頭結點是爲了操作的統一和方便而設立的,放在第一個結點之前;其數據域一般無意義(但是可以存儲鏈表的長度)
頭指針具有表示作用,所以常常用頭指針表示鏈表的名字; 有了頭結點,在第一個結點前插入和刪除第一個幾點時,操作與其他結點就統一了。
無論鏈表是否爲空,頭指針均不爲空。 頭指針是鏈表的必要元素 頭結點不一定是鏈表的必須要素。

最後總結:

  1. 鏈表結點包括數據域和指針域
  2. 鏈表是由n 個結點鏈結成,第一個結點的存儲位置叫做頭指針,最後一個結點的指針爲“空”

相較於順序表的優點:

  • 定義時不用規定長度;
  • 存儲的元素個數不受限制;
  • 插入和刪除元素時,不用移動其它元素。

好了,看到這裏的時候。我們就要開始我們的老規矩準備說再見了。
這次這次給大家普及了一點鏈表的知識,下一篇文章我會帶大家學習“鏈表”的大兒子“單鏈表”
如果覺得本篇文章對你有幫助的話,麻煩各位兄弟萌點個贊幫忙轉發一下~
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章