為什么數組從0開始編號


為什么數組從0開始編號

數組對一個程序員來說再熟悉不過了,幾乎所有的編程語言都有數組,它是最基本的數據結構之一。

剛開始學數組的時候,總是很納悶,為什么它從0開始編號,而不是從更符合我們思維習慣的1開始呢?帶着這個問題往下看。

什么是數組

在編程的過程中,我們經常要用到數組,但是你能夠用專業的詞匯來描述什么是數組嗎?

數組(Array)是一種線性表數據結構,它用一組連續的內存空間,來存儲一組具有相同類型的數據。

線性表

線性表(linear list)是指具有n個相同特性的數據元素組成的有限序列,你可以理解為“把所有數據用一根線串起來,再存儲到物理空間中”,從圖中可以明顯的看出它最多只有前和后兩個方向(節點)。

 

除了數組,鏈表、隊列和棧也是線性表結構(線性表既可以順序存儲,也可以鏈式存儲)

非線性表

與線性表對應,非線性表是指一個節點元素可能有多個直接前驅和多個直接后繼,比如樹和圖

 

連續的內存空間和相同的數據類型

同一個數組中的數據類型都是一樣的,並且它們連續存儲在內存中,所以我們可以對數組內容進行隨機訪問。隨機訪問這個過程是怎么實現的呢?

計算機會給每個內存單元分配一個地址,通過地址來訪問內存中的數據。當它需要隨機訪問數組中的某個元素時,首先會通過尋址公式,計算出該元素存儲的內存地址,然后對其進行讀取操作,尋址公式為

 a[i]_address = base_address + i * data_type_size //其中i表示數組中第幾個元素

我們拿一個長度為 10 的 int 類型的數組 int[] a = new int[10]來舉例。在這個圖中,計算機給數組 a[10]分配了一塊連續內存空間 1000~1039,其中,內存塊的首地址為 base_address = 1000,因為存儲的是整數,所以data_type_size = 4。根據公式,我們很容易就能得到這個數組中某個元素在內存中的地址。

 

從內存上看,我們可以理解為什么大部分編程語言中的數組下標是0開始,更准確的講它不是下標而是代表偏移(offset)。如果用a來表示數組的首地址,a[0]是它偏移0的位置(就是首地址),a[2]代表是偏移2 * data_type_size的位置,也就是第三個元素的地址,a[i]就表示偏移i * data_type_size的位置。如果從1開始編號的話,那么計算數組a[i]的內存地址公式就會變為

 a[i]_address = base_address + (i-1) * data_type_size

對於CPU來說,多做了一次減法指令。

還有一個原因就是歷史遺留問題,因為C語言使用0開始計數數組下標,后面的Java、C#等語言也都效仿了C語言,繼續沿用該習慣.但現在有的語言也不是從0開始計數,比如Lua,Matlab等.(部分內容及圖片參考王爭老師的數據結構與算法之美)

數組的增刪查操作

查找

前面已經講過,可以通過下標訪問數組中的元素,由於它是連續存儲的,訪問的時間復雜度是O(1).

添加

假設我們有一個數組,長度為n,要在它第k個位置上插入數據,要進行什么操作呢?為了空出第k個位置給新插入的數據,k~n這部分的數據都需要往后挪一位,那么它的平均時間復雜度為O(n).

 

刪除

刪除操作於添加類似,為了保持內存的連續,不出現空洞,需要將刪除元素后面的元素向前移,平均時間復雜度也為O(n)

如果對時間復雜度的概念不了解,可以查看算法復雜度分析

總結

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM