數組
-
數組是一種線性的結構
-
在數據中的內存地址是連續的,這也就是在數組中爲什麼要指定數組的大小,只有在連續空間內數組才能成立。
-
在一個數組裏面存儲的數據結構都是相同的
數組的特點
下圖是int[] a = new int[10] 數組結構。在下圖可以看到數組的內存地址都是連續的。由於int
在Java佔用4個字節。可以看到 每個空間都佔用4個字節。
當數組進行插入操作時,需要將插入位置的元素整體向後移動一位,int[3] 到**int[6] **的位置都要像後面移動一位,所以說數組在進行插入操作時是比較耗時的。當數組需要在第一位插入元素時,數組的需要整體向後移動,時間複製度就會變成O(n)
,當數組在最後一位時數組的時間複製度就是O(1)
,所以數組的評價時間複製度位O(n/2)
,也是就是O(N)
。
當數組需要刪除操作時,也需要進行數據數據的移動,時間時間複製度也是O(n)
在Java中ArrayList 也是通過數組實現的,ArrayList最大的優勢就是將很多數組的操作的細節封裝起來和動態擴容。
在使用ArrayList時如果可以需要使用的大小可以給ArrayList設置初始值,省掉很多次內存申請和數據搬移操作,避免在擴容時消耗掉部分性能。
數組的基本操作
public class ArraysTest {
private int size;
private int[] data;
private int index; //當前以存的數據大小
public ArraysTest(int size) {
this.size = size;
this.data = new int[size];
this.index =0;
}
public void print(){
for (int i = 0; i < size ; i++) {
System.out.printf(data[i]+" ");
}
}
//插入元素
public void insert(int loc,int n){
if (index++ < size){
for (int i = size -1; i > loc ; i--) {
data[i] = data[i-1];
}
data[loc] = n;
}
}
public void delete(int loc){ //O(n)
for(int i = loc ; i < size ; i++){
if(i != size - 1){ //怕越界所以加一個判斷
data[i] = data[i + 1];
}else{
data[i] = 0; //默認爲0 就是沒存數據的
}
}
index -- ;
}
public void update(int loc,int n){
data[loc] = n;
}
public int get(int loc){
return data[loc];
}
}
爲什麼大部分的數組的起始位是0
在數組存儲的內存模型上可以看到,數組的 下標 最準確的定義應該是 偏移(offset)。如果用a來表示數組的首先地址,a[0]的偏移位置爲0的位置,也是a[k]表示偏移k個 type_size 的位置,在計算a[k]的內存地址只需要使用這個公式:
a[k] _address = base_address + k * type_size
如果數組是從1開始,那麼a[k]的計算方式就是
a[k] _address = base_address + (k -1)* type_size
當每次進行訪問時,數組元素就會多了一次減法運算,對於cpu來說,就是多了一次減法運算。
C 語言設計使用0作爲數組的下標,在之後其他語言都模仿了C 語言,在設計上就可以減低學習成本。