遵從所有教材以及各類數據結構相關的書書籍,我們先從線性表開始入門。今天這篇文章更偏概念,是關於有線性表的一個知識點的匯總。
上文說過,物理結構是用於確定數據以何種方式存儲的。其他的數據結構(樹、圖)、算法等基本都是建立在這樣一個物理結構之上的,也可以說,物理結構就是數據結構的根本。在這里,我們先介紹兩個物理結構,也是我們將來學習數據結構的基石,它們就是順序表和鏈表。
順序表
不扯復雜的定義,不扯什么數學表達式,我們最直觀的理解,順序表就是數組。
是不是非常簡單,沒錯,在 PHP 或者 C 的世界中,我們就把順序表定義為數組,而相同的名詞還包括:順序存儲、順序結構等。只要看到這種名詞,馬上想到數組就可以了。當然,在 Java 中,我們也可以將 List 這類的集合當成是順序存儲結構。不過需要注意的是,Java 的 HashMap ,在 PHP 中是以鍵值對形式定義的數組,它們是哈希表(Hash),從形式上來說,他們並不是順序的。在這里我們一定要記住,像數組下標遞增這樣順序結構的才是順序存儲結構。
順序表一般占用連續的內存空間。不僅邏輯上,連物理空間上都是相鄰連續的。
鏈表
鏈表一般在 C 中會定義為一個結構體,其中包括數據和指向下一個鏈表的指針,它不是順序的,雖然邏輯是有順序的(按指針指向),但在物理是可以分開的。也就是說,鏈表不用占用連續的內存空間,不需要在初始化的時候像數組一樣給定長度。
在 PHP 中,我們沒有結構體這種語法形式,所以我們直接使用類來表示鏈表結構。
class Node{
public $data;
public Node $next;
}
這就是一個簡單的鏈表結構,我們可以把它叫做一個“結點”。data 中存放我們要保存的數據,可以是任意類型。而 next 則是我們下一個鏈表結點。如果我們需要簡單的遍歷鏈表,直接不停的調用 next 直到它為空即可。
while($n->next){
$n = $n->next;
echo $n->data, PHP_EOL;
}

上圖就是關於鏈表的邏輯狀態以及它的遍歷方向。具體的鏈表操作相關函數我們將在后面的文章中進行講解。
鏈表有很多種形式,上面我們定義的是一個簡單的單向鏈表。我們還可以定義雙向鏈表(加一個 prev 指向上一個結點),循環鏈表(最后一個next指回第一個結點)以及雙向循環鏈表(最后一個next指回第一個結點,第一個的 prev 指向最后一個結點)。關於這些內容,我們也會放到后面的文章中一一講解。
線性表
了解了順序表和鏈表之后,我們最后就來說說線性表。
其實,順序表和鏈表這兩種物理結構在默認狀態下所實現的就是“順序表”這個邏輯數據結構。
順序表:由n(n>0)個數據特性相同的元素構成的有限序列(嚴蔚敏版)
注意幾個關鍵點:
-
有限:數組長度、鏈表內存大小
-
序列:邏輯有序(數組是邏輯和物理都有序,鏈表是邏輯有序而物理無序)
-
數據特性相同:PHP 中不明顯,C 或 Java 中數組是固定類型的,而且也要給一個初始長度
為什么說線性表這么重要呢?我們想想 MySQL 這樣一行一行存儲數據的關系型數據庫,一張數據表不就是一個線性表嗎?特別是我們做 PHP 的程序員,天天都是在和數組(數據庫讀出來的數據一般都放到數據中)打交道(當然,我們用哈希可能更多些),也就是說,我們在做開發的時候,天天都在接觸這個東西,你說它重要不重要。
而 樹 和 圖 這些數據結構卻並不是線性表,在現實的歸類中,它們是屬於 非線性表 的范疇的。線性表在個很大的特點是只有前后關系,不管是鏈表還是數組,它們都是遵循着這種前后關系的,但是在 樹 和 圖 中,除了前后之外,還有上下左右等更復雜的關系。雖說它們的基本表現形式依然是使用數組和鏈表,但是從嚴格的角度來說,或者從考試面試的角度來說,它們真的不屬於線性結構,而應該划分到 非線性結構 中。
總結
今天這篇文章是學習數據結構中基礎的基礎。當然,有條件的最好還是看看 C 用結構體是如何定義數組、鏈表的,PHP 在底層已經幫我們解決了太多問題,所以這些原始的語法結構我們已經用不到了。能夠用 C 來學習數據結構是更加推薦的形式。
下一篇文章我們將介紹的是順序表(數組)的線性表相關邏輯操作。
參考資料:
《數據結構》第二版,嚴蔚敏
《數據結構》第二版,陳越
《數據結構高分筆記》2020版,天勤考研
===============
關注公眾號:【硬核項目經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、項目管理學習資料
知乎、公眾號、抖音、頭條搜索【硬核項目經理】
B站ID:482780532
