1. 程式人生 > >資料結構與演算法---陣列

資料結構與演算法---陣列

陣列的定義

陣列是一種線性表資料結構。它用一組連續的記憶體空間,來儲存一組具有相同型別的資料。

其中有幾個重要的概念:

  • 線性表
    • 線性表就是資料排成像線一樣的結構。每個線性表最多隻有前和後兩個方向。
    • 是線性表的資料結構有:
      • 陣列
      • 佇列
      • 連結串列
  • 非線性表
    • 非線性表則與線性表相反,資料並不是簡單的前後關係。
    • 非線性表的資料結構有:
  • 連續的記憶體空間
    • 陣列在記憶體中的儲存方式是一組給定長度的連續的空間。
    • 連續的空間才使得陣列可以實現通過下標隨機訪問。
    • 高階語言中的陣列能動態擴容均是二次封裝之後的結果,最底層的資料初始化的時候就已經指定好了該陣列的長度。
  • 儲存相同型別的資料
    • 相同型別+連續空間使得陣列可以通過下標隨機訪問。

陣列的原理

陣列示例

如圖所示,這是一個長度為5的int陣列arr,我們假設起始的記憶體地址為1000,那麼第一個元素的記憶體地址範圍就是:1000-1003,這是因為一個int佔4個位元組。那麼如果我們想要訪問最後元素arr[4],我們可以很容易的通過起始地址計算出來,1000+4*4 = 1016。那麼最後一個元素就是記憶體地址1016-1019。這就是陣列隨機訪問的原理,並且通過前面的算式,我們可以得出因為陣列下標訪問的計算與陣列長度n無關,因此下標訪問的時間複雜度為O(1)

陣列的特點

  • 可以直接隨機訪問(依據下標訪問)其中的任意資料
  • 隨機訪問資料非常高效
  • 低效的插入和刪除

前兩點上面原理裡面已經解釋的很清楚了,這裡我們聊聊陣列的插入與刪除。

因為陣列是一組連續的記憶體空間,那麼不管我們是要往裡面插入或者刪除,都必須涉及到陣列插入、刪除節點之後的資料的移動。那麼最理想的情況:直接在陣列末尾插入、刪除元素,時間複雜度為O(1)。最差情況:在陣列開啟插入、刪除元素,時間複雜度為O(n)。因此資料的插入、刪除操作是非常低效的。

運算元組的小技巧

既然我們已經知道了陣列插入、刪除的效率問題,那麼我們可以有一些小技巧來優化我們的操作。

  • 陣列插入操作:如果我們要插入的陣列是一個本身就無序的陣列,那麼我們可以不需要將資料插到指定位置,直接插入末尾即可,這樣時間複雜度為O(1),效率極高。
  • 陣列刪除操作:如果我們有需求涉及到頻繁的刪除陣列中的資料,因為每次刪除都會造成資料的移動,非常的消耗效能,我們可以先記錄下已經刪除的資料,而不是真正的從陣列中刪除,當陣列空間不夠時或者刪除操作全部執行完之後,再一次性的刪除全部對應的資料並移動剩餘資料,這樣大大減少了資料 搬移的次數,提高執行效率。(這也是JVM標記清除垃圾回收演算法的核心思想)