數據結構精講:從原理到實戰--學習筆記01

數據結構精講:從原理到實戰–學習筆記01

本筆記是記錄學習 《數據結構精講:從原理到實戰》,作者是:蔡元楠,Google Brain資深工程師。

如有侵權,聯繫刪除!

數組內存模型

一維數組

當定義一個數組後

int[] data = new int[5];

內存模型如圖所示
Alt
這種連續空間的內存模型揭示了一個重要特性:隨機訪問(random access)
random access:可以用同等的時間訪問到一組數據中的任意一個元素。

我們可以用如下代碼獲取數組中的值:

data[0]

這種從 0 開始進行索引的編碼方式被稱爲是“Zero-based Indexing
我們可以通過以下公式獲取數組特定元素:

base_address + index * date_size = target_address

此公式保證了,不同的數組元素達到的時間是相同的。

二維數組

一般稱爲一維數組爲 向量(Vector)表(Table),數學上稱二維數組爲 矩陣(Matrix)

按照以下代碼聲明一個矩陣:

int[][] data = new int[2][3]

基於這個二維數組,我們是無法確定 data[0][1]的內存地址,因爲這個問題涉及到二維數組在內存中的尋址方式。其本質是 行優先(Row-Major Order) 還是 列優先(Column-Major Order)

Alt
在行優先內存模型中,每一行的相鄰元素保存在相鄰的連續內存空間中,這個二維數組內存模型如下所示:
Alt
我們可以按照以下公式獲取data[i][j]裏的元素:

base_address + data_size * (i * number_of_column + j)

在列優先內存模型中,每一列的相鄰元素保存在相鄰的連續內存空間中,這個二維數組內存模型如下所示:
Alt
我們可以按照以下公式獲取data[i][j]裏的元素:

base_address + data_size * (i * number_of_row + j)

CPU 在讀取內存數據的時候,通常會有一個 CPU 緩存策略。也就是說,在 CPU 讀取程序指定地址的數值時,CPU 會把和它地址相鄰的一些數據也一併讀取並放到更高一級的緩存中,比如 L1 或者 L2 緩存。當數據存放在這種緩存上的時候,讀取的速度有可能會比直接從內存上讀取的速度快 10 倍以上。

數組特點

高效的訪問和低效的插入刪除

數組的訪問時間複雜度是 O(1)

對於保存基本類型Primitive Type)的數組來說,它們的內存大小在一開始就已經確定好了,我們稱它爲靜態數組(Static Array)。靜態數組的大小是無法改變的,所以我們無法對這種數組進行插入或者刪除操作。但是在使用高級語言的時候,比如 Java,我們知道 Java 中的 ArrayList 這種 Collection 是提供了像 add 和 remove 這樣的 API 來進行插入和刪除操作,這樣的數組可以稱之爲動態數組(Dynamic Array)

爲了維持數組內存中的連續性,當插入一個數據時,需要把待插入節點及之後所有的數據都拷貝,然後給數組擴容,把拷貝的數據放入待插入節點之後,最後再在待插入節點插入目標值。
刪除元素同理,所以插入刪除時間複雜度是 O(n)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章