數據結構與算法基礎(二)之線性表的鏈式存儲與指針的概念

       上一節我們討論到了線性表的順序存儲結構的缺點,那就是在進行插入和刪除操作的時候需要移動大量的元素,爲了解決這個問題,我們可以想到的方法有很多,比如說在相鄰元素之間留出一定的位置給待插入的元素使用,但是這樣非常浪費空間,而且插入刪除操作的具體位置和元素的數量是未知的,這樣並不是最好的解決方法。

       這個時候就需要我們在C語言學習時接觸到的“指針”上場了。

       首先,什麼是指針呢?指針就編程語言中的一個對象或變量,用來存儲某一個地址,這個地址的值直接指向points to存在電腦存儲器中另一塊存儲空間的值。作個比喻,假設將電腦存儲器當成一本書,一張內容記錄了某個頁碼加上行號的便利貼,可以被當成是一個指向特定頁面的指針;根據便利粘貼面的頁碼與行號,翻到那個頁面,把那個頁面的那一行文字讀出來,就相當於是對這個指針進行反參考的動作。(來自維基百科詞條指針

       線性表的鏈式存儲結構的特點是用一組任意的存儲單元存儲線性表的數據元素,這組存儲單元可以存在內存中未被佔用的位置。這一點和順序存儲結構不同,也就是說線性表的元素不一定要按照順序來,只需要放在任意內存未被佔用的位置即可。順序存儲結構每個數據元素只需要存儲一個位置就可以,而鏈式存儲結構中除了要存儲數據元素信息外還要存儲它的後繼元素的存儲地址(指針)。

       我們把存儲數據元素信息的域稱之爲數據域,把存儲後直接後繼位置的域稱爲指針域。指針域中存儲的信息稱爲指針或鏈。這兩部分信息組成結點(Node)。

      n個結點鏈接成一個鏈表,即爲線性表(a1,a2,a3.....,an)的鏈式存儲結構。我們把鏈表中第一個結點稱爲頭指針,最後一個節點指針爲空(NULL)。如下圖所示:


        關於線性表的順序存儲和鏈式存儲的區別,我想到一個例子來進行比喻。比如說我們去銀行櫃檯辦理銀行卡和體育課站隊列這兩種情景。前者,在櫃檯辦理業務時要去抽取一個號碼,拿到號碼之後只需要隨意找個位子等着自己被叫號即可,那麼不管顧客站在哪裏等待,依然是按照顧客抽號的順序來辦理業務的,叫到自己的號碼時便可以上前辦理業務。後者,體育課上要按照身高排隊列,排好之後如果有同學遲到晚來了,那麼就根據他的身高來確定他要插入的位置,相應地,這位同學所處位置之後的同學就要往後移動一個位置。

        假設p是指向線性表第i個元素的指針,則該結點ai的數據域我們可以用p->data的值是一個數據元素,結點ai的指針域可以用p->next來表示,p->next的值是一個指針。舉個例子,如果p->data=ai,那麼p->next->data=ai+1。

        單鏈表讀取元素的核心思想就是:工作指針後移。算法的時間複雜度依然取決於元素位置,如果在第一個位置那麼時間複雜度爲O(1),否則就要指針一個個後移直到找到那個元素。



易混淆的兩個概念:頭指針和頭結點

頭結點是指在單鏈表的第一個結點之前附設的一個結點。頭結點的數據域可以爲空也可以存儲如線性表長度等的附加信息。頭結點的指針域指向第一個結點的指針也就是第一個元素結點的存儲位置。

單鏈表中可以沒有頭結點但是不能沒有頭指針,如果沒有頭結點則直接指向第一個結點。



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