- 什么是數組?
數組(Array)是一種線性表數據結構。它用一組連續的內存空間,來存儲一組具有相同類型的數據。
- 特性
第一是線性表(Linear List)。顧名思義,線性表就是數據排成像一條線一樣的結構。每個線性表上的數據最多只有前和后兩個方向。其實除了數組,鏈表、隊列、棧等也是線性表結構。
第二個是連續的內存空間和相同類型的數據。正是因為這兩個限制,它才有了一個堪稱“殺手鐧”的特性:“隨機訪問”。但有利就有弊,這兩個限制也讓數組的很多操作變得非常低效,比如要想在數組中刪除、插入一個數據,為了保證連續性,就需要做大量的數據搬移工作。
- 說到數據的訪問,那你知道數組是如何實現根據下標隨機訪問數組元素的嗎?
我們拿一個長度為 10 的 int 類型的數組 int[] a = new int[10] 來舉例。在我畫的這個圖中,計算機給數組 a[10],分配了一塊連續內存空間 1000~1039,其中,內存塊的首地址為 base_address = 1000。
我們知道,計算機會給每個內存單元分配一個地址,計算機通過地址來訪問內存中的數據。當計算機需要隨機訪問數組中的某個元素時,它會首先通過下面的尋址公式,計算出該元素存儲的內存地址:
a[i]_address = base_address + i * data_type_size
其中 data_type_size 表示數組中每個元素的大小。
因為數組是連續存儲的,所以根據首地址和下標,通過尋址公式就能直接計算出對應的內存地址,找出數據。
常常會問數組和鏈表的區別,很多人都回答說,“鏈表適合插入、刪除,時間復雜度 O(1);數組適合查找,查找時間復雜度為 O(1)”。
實際上,這種表述是不准確的。數組是適合查找操作,但是查找的時間復雜度並不為 O(1)。即便是排好序的數組,你用二分查找,時間復雜度也是 O(logn)。所以,正確的表述應該是,數組支持隨機訪問,根據下標隨機訪問的時間復雜度為 O(1)。