學習數據結構Day2

以前學習過了數組的靜態實現方法,同時將數組的全部有可能實現的方法都統一實現了一遍,以後支持了泛型的相關java

 

概念,接下來就是如何對數組進行擴容的操做也就是實現動態數組。算法

 

private void resize(int newcapacity){  E[] newdata = (E[]) new Object[newcapacity];  for (int i = 0; i < newcapacity; i++) {  newdata[i] = data[i];  }  data = newdata;  }

 

在此處,咱們寫了一個關於resize的操做,其原理就是對就數組容量的擴容,擴容其原來的二倍。數組

 

同理,咱們還能夠進行對刪除操做的優化,若是刪完數據後,數組的容量有一半可能是不用的空間,咱們就能夠進行刪學習

 

掉一半的操做。優化

 

 public E remove(int index) {  if (index < 0 || index > size) {  throw new IllegalArgumentException("require index >= 0 and index > size!");  }  E ret = data[index];  for (int i = index + 1; i < size; i++) {  data[i - 1] = data[i];  }  size--;  data[size] = null; // loitering Objects != memory leak  if(size == data.length / 2){  resize(data.length/2);  }  return ret;  }

 

注意代碼的第11,12行 進行了優化。ui

 

至此,咱們就把數組的動態的實現整理完畢了。atom

 

接下來,我簡單的描述一下時間複雜度的分析。spa

 

O(1) O(n) O(lgn) O(nlogn) O(n^2)3d

 

大O是描述的算法運行時間和輸入數據之間的關係。code

 

O(n)中 n表示的是元素的個數  算法和n呈線性關係。

 

那麼O(n^2)則表示的是 成二次方的關係。

 

針對於不一樣的算法,咱們須要針對不一樣的變量進行變量控制,來肯定這個算法是不是最快的。

 

image.png

 

同理,刪除操做也是相應的時間複雜度。

 

在看完時間複雜度以後,咱們引入一個resize的時間複雜度分析。

 

對於添加的時間複雜度分析,咱們能夠看到,resize的時間複雜度分析是O(n),那麼咱們按最壞時間複雜度分析,

 

咱們就將添加的時間複雜度算爲O(n),可是並非每次添加元素咱們都要resize的 ,因此假設capacity = n,n+1次

 

addLast,觸發resize,總共進行2n+1次基本操做平均,每次addLast操做,進行兩次基本操做。這樣均攤計算,時間復

 

雜度是O(1)的!,同理removeLast()的時間複雜度也是O(1)的,可是,若是咱們綜合去看待這個方法時,就會出現問

 

題。在填滿數據後,我調用addLast()方法時,須要擴容,緊接着我又調用removeLast()方法,又開始縮容,一直這

 

樣下去,時間複雜度一直是O(n),這樣就產生了時間複雜度震盪。出現的緣由是:removeLast()時,過於着急,咱們

 

可讓他懶惰一些,也就是說能夠在等到size  ==  capacity/4時,纔將capacity減半。

 

image.png

 

這樣,咱們本身寫完的動態數組就完成了!

相關文章
相關標籤/搜索