陣列
定義:陣列(Array)是一種線性表資料結構。它用一組連續的記憶體空間,來儲存一組具有相同型別的資料(不同語言對陣列的定義標準不同,大多數語言要求同型別,而在JavaScript中,陣列中元素可以是不同型別)。
解釋:
1. 線性表
顧名思義,就是資料排成一條線一樣的結構。每個線性表上的資料最多有前後兩個方向。除了陣列之外,連結串列、佇列、棧等也是線性結構。與之對應的就是非線性表:資料之間不是簡單的前後關係。
複製程式碼


2. 連續的記憶體空間和相同型別的資料
陣列內的元素所佔用的記憶體空間相同且連續,正因為這兩點限制,陣列才有了——隨機訪問——的特性。我們知道計算機會給每個記憶體單元(1B)分配一個記憶體地址,通過地址來訪問。當計算機要隨機訪問陣列中的某個元素時,首先得找出該元素的記憶體地址,通過下面的定址公式來計算:a[i]_address = base_address + i * data_type_size
要注意的點:陣列適合查詢,查詢的時間複雜度為O(1)。是不準確的。正確的說法:陣列支援隨機訪問,根據下標的隨機訪問時間複雜度是O(1),僅需執行定址一行定址公式就可找到。
複製程式碼

低效的插入刪除
插入:
為保證陣列資料的連續性,在第k個位置上插入資料,如要保證陣列元素順序不變,則k~n這部分資料都需要往後移一位,此時k=n-1,最好的時間複雜度O(1),k=0,最壞的時間複雜度O(n)。每個位置插入的概率是一樣的1/n,所以平均時間複雜度(1+2+...+n)/n = O(n)。 如果不需要保證順序:

刪除:
同理插入每刪除一次,保證順序不變,則平均時間複雜度O(n)。如果在某些場景中,不一定要保證陣列中資料的連續性。則可以將多次刪除操作集中一次執行。每次要刪除的資料都進行標記,當陣列沒有更多空間儲存資料時,觸發一次真正的刪除操作。
警惕陣列的訪問越界問題:
這段C語言程式碼:C中只要不訪問受限記憶體,所有記憶體空間都可以自由訪問。




陣列下標為什麼從0開始
解釋:
- 下標確切定義應該是‘偏移量’,a[1]:偏移了一個位置。這樣定址公式:a[k]_address = base_address + k * type_size 如果從1開始:a[k]_address = base_address + (k-1)*type_size多了一步計算k-1。
- 歷史原因,最開始就設計從0開始,後邊的語言就一直沿用了。