數組——爲什麼下標從0開始呢?

什麼?

數組是一種線性表數據結構,用一組連續的內存空間來存儲具有同一種數據類型數據。

特點

  • 數組支持隨機訪問。
  • 數組的 插入刪除 操作比較低效。

隨機訪問

根據尋址公式:array[i] = base_address+i*data_type_size迅速找到對應下標 i 中數據,隨機訪問時間複雜度爲O(1)。

插入操作

  • 最好情況:插在末尾,時間複雜度爲O(1);
  • 最壞情況:插在開頭,時間複雜度爲O(n);
  • 一般情況,插在中間k位置:
    1. 如果數組存放數據有特定的順序或關聯,則涉及插入後數據的移動,考慮概率的情況,平均時間複雜度爲O(n);
    2. 如果數組僅存放數據,數據沒有特定順序,則可以將k位數據移到最後,再插入k位,時間複雜度位O(1);

刪除操作

  • 最好情況:刪除末尾,O(1);
  • 最壞情況:刪除開頭,O(n)
  • 一般情況,刪除中間k位置:
    1. 無論數組存放數據是否有序,刪除k位的元素後需要移動k+1~n的數據,頻繁的刪除操作會導致頻繁的數據搬移工作;
    2. 如果不追求數組中存放數據的連續性,可以將多次刪除操作集中到某一次執行,每次刪除操作僅僅做刪除標記,每次刪除記錄下被刪除的數據,當數組沒有更多的空間,則可以觸發一次真正的刪除操作,這樣就可以減少刪除產生的數據搬移的工作。

數組越界

數組按照下標的隨機訪問,本質是訪問基於base_address做偏移量的計算得到的內存地址,只要這塊內存可以使用,那麼即使下標已超出數組長度,程序也不會報錯。例如下面的C程序:

int main(int argc, char* argv[]){
    int i = 0;
    int arr[3] = {0};
    for(; i<=3; i++){
        arr[i] = 0;
        printf("hello \n");
    }
    return 0;
}

但是不是所有的高級語言如C一樣把檢查數組越界的工作丟給程序員,Java就對數組越界問題做了檢測,會拋出 java.lang.ArrayIndexOutOfBoundsException異常。

	public static void main(String[] args) {
        int[] arr = new int[3];
        arr[0]=11;
        for(int i=0;i<=3;i++){
            arr[i]=0;
            System.out.println("hello ");
        }
    }

Java中容器類ArrayList和數組

  • ArrayList 將很多數組操作的細節封裝了起來,比如數組的插入、刪除時需要搬移其他數據等;
  • ArrayList支持動態擴容,當空間不夠時會自動擴容至當前的1.5倍,擴容涉及到內存空的申請等操作比較耗時,所以最好可以提前指定大小。
  • ArrayList無法存儲基本數據類型,例如int、double等,需要用封裝類,這裏就涉及到自動裝箱和拆箱或有一定的性能損耗,如果特別關注性能或者希望使用基本類型,就可以用數組。
  • 多爲數組Object[][]相比ArrayList<ArrayList< Object > > 更加直觀。
  • 業務開發中,我們可以直接使用容器類,如果是特別底層的開發,直接使用數組可能會更合適。

熄燈

這下應該指導爲什麼一般數組下標不從1開始而從0開始了吧!下標其實就是偏移量,如果從1開始的話尋址的時候還需要做i-1這樣的操作,這就需要執行一次減法指令,像這麼基礎的數據結構,當然追求極致的性能,所以從0開始比較合理。(其實第一個人是從0開始的,後面大家都跟着用習慣了!!!)

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