數據結構與算法學習筆記之 從0編號的數組

前言

數組看似簡單,但掌握精髓的卻沒有多少;他既是編程語言中的數據類型,又是最基礎的數據結構;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.業務開發,使用容器足夠,開發框架,追求性能,首先數組。

 

爲何數組要從 0 開始編號?

因爲數組是經過尋址公式,計算出該元素存儲的內存地址:
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

版權:本文版權歸做者轉載:歡迎轉載,但未經做者贊成,必須保留此段聲明;必須在文章中給出原文鏈接;不然必究法律責任

相關文章
相關標籤/搜索