資料結構與演算法之美專欄學習筆記-陣列
什麼是陣列
陣列(Array)是一種線性表資料結構。它用一組連續的記憶體空間,來儲存一組具有相同型別的資料。
線性表
線性表就是資料排成像一條線一樣的結構。
常見的線性表結構:陣列,連結串列、佇列、棧等。
非線性表有:二叉樹、圖、堆等。
連續的記憶體空間和相同型別的資料
優點:兩限制使得具有隨機訪問的特性
缺點:刪除,插入資料效率低
陣列怎麼根據下標隨機訪問的
通過定址公式,計算出該元素儲存的記憶體地址:
a[i]_address = base_address + i * data_type_size
為何陣列插入和刪除低效
插入
若有一元素想往int[n]的第k個位置插入資料,需要在k-n的位置往後移。
最好情況時間複雜度 O(1),最壞情況複雜度為O(n),平均複雜度為O(n)
如果陣列中的資料不是有序的,也就是無規律的情況下,可以直接把第k個位置上的資料移到最後
然後將插入的資料直接放在第k個位置上,這樣時間複雜度就將為 O(1)了。
刪除
與插入類似,為了保持記憶體的連續性。
最好情況時間複雜度 O(1)、最壞情況複雜度為O(n)、平均複雜度為O(n)
提高刪除效率的方法
將多次刪除操作中集中在一起執行,可以先記錄已經刪除的資料,但是不進行資料遷移,而僅僅是記錄。
當發現沒有更多空間儲存時,再執行真正的刪除操作。這也是 JVM 標記清除垃圾回收演算法的核心思想。
陣列訪問越界問題
C語言中的資料越界是一種未決行為,一般比較難發現的邏輯錯誤。相比之下,Java會有越界檢查。
用陣列還是容器
二者的特點
陣列先指定了空間大小
容器如ArrayList可以動態擴容。
使用陣列的情形
1.希望儲存基本型別資料,可以用陣列
2.事先知道資料大小,並且操作簡單,可以用陣列
3.直觀表示多維,可以用陣列
4.業務開發,使用容器足夠,開發框架,追求效能,首先陣列。
為什麼陣列要從 0 開始編號
由於陣列是通過定址公式,計算出該元素儲存的記憶體地址:
a[i]_address = base_address + i * data_type_size
如果陣列是從 1 開始計數,那麼就會變成:
a[i]_address = base_address + (i-1)* data_type_size
對於CPU來說,多了一次減法的指令。
當然,還有一定的歷史原因。