數組看似簡單,但掌握精髓的卻沒有多少;他既是編程語言中的數據類型,又是最基礎的數據結構;html
一個小問題:算法
爲何數據要從0開始編號,而不是 從1開始呢?編程
帶着問題進入學習數組
數組(array)是一種線性表數據結構,它用一組連續的內存空間來儲存一組具備相同類型的數據。數據結構
咱們從定義來分析:框架
線性表:編程語言
是數據排成像一條線同樣的結構。每一個線性表上的數據最多有先後兩個方向。諸如數組,鏈表,隊列,棧等都是線性表結構。性能
連續的內存空間和相同類型的數據:學習
這個特性是數組「隨機訪問」速度飛快的原因,這也致使了從數組中刪除、插入數據,爲了保證連續性,須要大量的工做量spa
計算機會給每一個內存單元分配一個地址,計算機經過地址來訪問內存中的數據。
當計算機隨機訪問數組中的某個元素時,它會首先經過下面的尋址公式,計算出該元素的內存地址:
a[i]_address = base_address + i * data_type_size
data_type_siza表示數組中的每個元素的大小。若是是int類型的數據,data_type_size爲4個字節;
鏈表適合插入、刪除,時間複雜度爲O(1),數組適合查找,可是這裏要注意一下,時間複雜度並非O(1),即使是排好序的數組,你用二分法查找,時間複雜度也是O(logn),
正確的描述爲:數組支持隨機訪問,根據下標隨機訪問的時間複雜度爲O(1)
假設數組的長度爲 n,如今,若是咱們須要將一個數據插入到數組中的第 k 個位置,爲了把第 k 個位置騰出來,給新來的數據,咱們須要將第 k~n 這部分的元素都順序地日後挪一位,下面咱們分析一下時間複雜度
若是在數組的末尾插入元素,那就不須要移動數據了,這時的時間複雜度爲 O(1),但若是在數組的開頭插入元素,那全部的數據都須要依次日後移動一位,因此最壞時間複雜度是 O(n),由於咱們在每一個位置插入元素的機率是同樣的,因此平均狀況時間複雜度爲 (1+2+…n)/n=O(n)
若是數組中的數據是有序的,咱們在某個位置插入一個新的元素時,就必須按照剛纔的方法搬移 k 以後的數據,若是數組中存儲的數據並無任何規律,數組只是被看成一個存儲數據的集合。在這種狀況下,若是要將某個數組插入到第 k 個位置
爲了不大規模的數據搬移,咱們還有一個簡單的辦法就是
直接將第 k 位的數據搬移到數組元素的最後,把新的元素直接放入第 k 個位置。
和插入相似,
若是刪除數組末尾的數據,最好狀況時間複雜度爲 O(1);
若是刪除開頭的數據,則最壞狀況時間複雜度爲 O(n);
平均狀況時間複雜度也爲 O(n)
將屢次刪除操做中集中在一塊兒執行,能夠先記錄已經刪除的數據,可是不進行數據遷移,而僅僅是記錄,當發現沒有更多空間存儲時,再執行真正的刪除操做。這也是 JVM 標記清除垃圾回收算法的核心思想。
C語言中的數據越界是一種未決行爲,通常比較難發現的邏輯錯誤。相比之下,Java會有越界檢查。
數組先指定了空間大小,容器如ArrayList能夠動態擴容。
1.但願存儲基本類型數據,能夠用數組
2.事先知道數據大小,而且操做簡單,能夠用數組
3.直觀表示多維,能夠用數組
4.業務開發,使用容器足夠,開發框架,追求性能,首先數組。
因爲數組是經過尋址公式,計算出該元素存儲的內存地址:
a[i]_address = base_address + i * data_type_size
若是數組是從 1 開始計數,那麼就會變成:
a[i]_address = base_address + (i-1)* data_type_size
以上內容爲我的的學習筆記,僅做爲學習交流之用。
歡迎你們關注公衆號,不定時乾貨,只作有價值的輸出
做者:Dawnzhang
出處:http://www.javashuo.com/article/p-mrqlqxsk-gh.html
版權:本文版權歸做者轉載:歡迎轉載,但未經做者贊成,必須保留此段聲明;必須在文章中給出原文鏈接;不然必究法律責任