咱們的數組

上一篇,咱們講完算法複雜度,接下來咱們來見一見咱們很是熟悉的朋友--數組。html

咱們平時使用的數組是數據類型,可是數組不只僅是數據類型更是一種基礎的數據結構。算法

 

數組的定義

咱們來看看數組定義:分類連續的內存空間來存儲相同類型集合的線性表數據結構。數組

線性表+連續內存+相同類型 着三個特性合併出了數組的必殺技:隨機訪問。數據結構

那麼數組是怎麼實現下標隨機訪問的呢?架構

 

隨機訪問

根據頭節點和固定類型具體長度,就能夠實現隨機訪問。工具

search[i]_address = base_address + i*data_type_sizespa

雖然對於訪問來說,下標隨機訪問的複雜度爲O(1)3d

 

插入和刪除

可是對於插入和刪除來講日子就不是那麼好過了。調試

由於數組要保證內存的連續性這個特性,因此插入和刪除都是比較低效的,咱們具體來看看插入和刪除。htm

 

插入:咱們在任意節點前插入,那麼後面的元素必須後移一位來保證連續性

假設咱們有一個數組爲 int[n] =[1,2,3,4,5,......,n]

咱們在左側頂頭插入呢?後面的所有都移動,因此算個複雜度爲O(n),咱們上面一篇提到過的最差狀況時間複雜度

與此對應的是末尾插入,完美,啥都不用幹,這就不用說了就是 最好狀況時間複雜度。

那麼若是在中間任意位置出現呢?多種狀況,因此就是平均狀況時間複雜度

概括一下:

數組左側頂頭插入元素,最壞狀況時間複雜度 O(n)

數組末尾追加插入元素:最好狀況時間複雜度 O(1)

數組中間狀況插入元素,平均狀況時間複雜度 O(n)

 

插入平均時間複雜度

咱們這裏來驗證一下,數組下標隨機訪問的平均時間複雜度爲何是O(n):

對於一個  int[n] = [1,2,3,4,5,......,n]

我從頭依次進行插入,那麼對應的移動數組次數是

(n-1) 

(n-2) 

...

0

 

對於平均時間複雜度來說,能夠插入的空先後兩端2個+中間n-1,即 n+1 種狀況

這裏的每一個插入點發生的狀況機率是同樣的都是  1 / (n+1)

因此,平均時間複雜度爲移動次數*發生的機率

n * [1/(n+1)]

(n-1) * [1/(n+1)]

...

1 * [1/(n+1)]

0 * [1/(n+1)]

簡化一下:(0+1+2+3...n)  /  (n+1)   => [(n-1)/2] * n + n / (n+1)

算法複雜度去除係數、常量、低階,這裏的平均狀況時間複雜度是O(n)

平常開發中,若是咱們遇到有序數組,那咱們必須在插入的同時,後移後面的全部位置。

可是若是數組對排序不敏感,那麼咱們的插入能夠在後面追加,這樣避免了移動數組,複雜度就是O(1)

 

刪除:若是咱們刪除數組中的元素,爲了保持數組的連續性,依然須要搬運數組元素。

因此刪除操做和插入操做的最好、最壞、平均複雜度是對應的。

其實咱們也能夠加一個刪除標記,在空閒的時候進行刪除重排序。

 

訪問越界問題

 

對於以上這段C程序來講,上面這段代碼,咱們在書寫的時候,沒有仔細檢查,使得<寫成了<=,這樣就會產生了越界問題。

前提條件:

一、由於不一樣的CPU架構不一樣的編譯器會有不一樣的內存分配策略:從高地址向低地址增加,或者從低地址向高地址增加。也就是大小端問題。

二、首先壓棧的是 i ,以後是數組arr。因此 i 的內存地址比arr中的元素高,而且 i 和arr中的元素相鄰,而且類型相同,也就是子節是對齊的。

 

因此當 arr [ 3 ] 這個地址越界訪問到了 相鄰的同類型的 i 這個變量的內存地址。arr[3] =0,其實也就是 i = 0,好吧,又從頭開始了,無限循環。

 

那麼爲何咱們平時使用的語言即使是越界也會程序異常終止。其實這是編譯器作的工做,編譯器不一樣,內存申請方式也不一樣。

咱們平時的編譯器已經幫咱們作好了代碼檢查等工做。因此避免了越界的狀況。

 

C# []、Array、ArrayList、List<T>

首先 [] ,就是咱們聲明簡單的數組,由於數組是連續的線性數據結構,因此不少操做微軟又給作了封裝。

Array ,就是微軟對數組進行的封裝類。下面又進一步衍生出了動態數組。

ArrayList,就是動態數組,裏面封裝了數組不少的操做。尤爲是動態擴容。泛型以後,又出了泛型列表。

List<T>是動態數組的泛型版本,避免了頻繁的裝箱拆箱,效率較高,也是咱們平時使用最頻繁的一種。

其實微軟已經開源了.NET Framework 源碼,詳細可查看此地址

還有一種方式,可使用遠程調試源碼,遠程下載源碼到本地,進行源碼調試:

工具  -》 調試 -》勾選 啓用源代碼單步調試

固然速度上確定會比本地代碼慢。

以上就是今天的內容。

相關文章
相關標籤/搜索