【學點數據結構和算法】01-數組

寫在前面: 博主是一名軟件工程系大數據應用開發專業大二的學生,暱稱來源於《愛麗絲夢遊仙境》中的Alice和自己的暱稱。作爲一名互聯網小白,寫博客一方面是爲了記錄自己的學習歷程,一方面是希望能夠幫助到很多和自己一樣處於起步階段的萌新。由於水平有限,博客中難免會有一些錯誤,有紕漏之處懇請各位大佬不吝賜教!個人小站:http://alices.ibilibili.xyz/ , 博客主頁:https://alice.blog.csdn.net/
儘管當前水平可能不及各位大佬,但我還是希望自己能夠做得更好,因爲一天的生活就是一生的縮影。我希望在最美的年華,做最好的自己

        先來解釋下博主爲什麼會在這個時候開設一個專欄來學習【數據結構和算法】。

        就像各位所知道的,在如今的互聯網招聘中,面試官越來越着重考察應聘者的一個基礎實力。像數據結構與算法,如果一點沒接觸,連門檻都進不去(尤其是大廠,不會算法基本沒戲)。而博主,作爲一個00後,大二的學生,很不幸地在過去一年多時間裏幾乎沒有接觸過數據結構和算法。雖然我並不抱着實習就能進大廠的打算,但是從長遠的角度出發,早點開始學習數據結構和算法,並非一件壞事。至少等到實力充足了,例如工作了兩三年,完全可以通過社招的形式憑本事進大廠。所以在閒暇之餘,就自己開設了一個專欄,用於沒事的時候寫寫,就當是爲自己補充能量了吧哈哈。
在這裏插入圖片描述
        好了,不多嗶嗶了,在正式開始之前,先奉上一張大佬製作的思維導圖(來源:https://www.cnblogs.com/zhanghaodong/p/10281923.html)。可謂總結的非常精闢,而我作爲一個入門級選手,決定後面就按着這個路線去學習。
在這裏插入圖片描述
        本篇我們先來學習數組。

基本概念

        數組是由有限個相同類型的變量所組成的有序集合,它的物理存儲方式是順序存儲,訪問方式是隨機訪問。利用下標查找數組元素的時間複雜度是O(1),中間插入,刪除數組元素的時間複雜度是O(n)
在這裏插入圖片描述

特點

  • 在內存中,數組是一塊連續的區域
  • 數組需要預留空間(數組的空間在編譯階段就需要進行確定,所以需要提前給出數組空間的大小),預先申請可能會浪費內存空間,即數組空間利用率低
  • 在數組起始位置處,插入數據和刪除數據效率低。
  • 隨機訪問效率很高,時間複雜度可以達到O(1)
  • 數組開闢的空間,在不夠使用的時候需要擴容,擴容的話,就會涉及到需要把舊數組中的所有元素向新數組中搬移
  • 數組的空間是從分配的

常用操作

插入數據

  /**
     * 數組插入元素
     * @param index  插入的位置
     * @param element  插入的元素
     */
    public void insert(int index, int element) throws Exception {
        //判斷訪問下標是否超出範圍
        if(index<0 || index>size){
            throw new IndexOutOfBoundsException("超出數組實際元素範圍!");
        }
        //如果實際元素達到數組容量上線,數組擴容
        if(size >= array.length){
            resize();
        }
        //從右向左循環,逐個元素向右挪一位。
        for(int i=size-1; i>=index; i--){
            array[i+1] = array[i];
        }
        //騰出的位置放入新元素
        array[index] = element;
        size++;
    }

數組擴容

    /**
     * 數組擴容
     */
    public void resize(){
        int[] arrayNew = new int[array.length*2];
        //從舊數組拷貝到新數組
        System.arraycopy(array, 0, arrayNew, 0, array.length);
        array = arrayNew;
    }

刪除元素

/**
     * 數組刪除元素
     * @param index  刪除的位置
     */
    public int delete(int index) throws Exception {
        //判斷訪問下標是否超出範圍
        if(index<0 || index>=size){
            throw new IndexOutOfBoundsException("超出數組實際元素範圍!");
        }
        int deletedElement = array[index];
        //從左向右循環,逐個元素向左挪一位。
        for(int i=index; i<size-1; i++){
            array[i] = array[i+1];
        }
        size--;
        return deletedElement;
    }

輸出數組

    /**
     * 輸出數組
     */
    public void output(){
        for(int i=0; i<size; i++){
            System.out.println(array[i]);
        }
    }

完整代碼

public class MyArray {

    private int[] array;
    private int size;

    public MyArray(int capacity){
        this.array = new int[capacity];
        size = 0;
    }

    /**
     * 數組插入元素
     * @param index  插入的位置
     * @param element  插入的元素
     */
    public void insert(int index, int element) throws Exception {
        //判斷訪問下標是否超出範圍
        if(index<0 || index>size){
            throw new IndexOutOfBoundsException("超出數組實際元素範圍!");
        }
        //如果實際元素達到數組容量上線,數組擴容
        if(size >= array.length){
            resize();
        }
        //從右向左循環,逐個元素向右挪一位。
        for(int i=size-1; i>=index; i--){
            array[i+1] = array[i];
        }
        //騰出的位置放入新元素
        array[index] = element;
        size++;
    }

    /**
     * 數組擴容
     */
    public void resize(){
        int[] arrayNew = new int[array.length*2];
        //從舊數組拷貝到新數組
        System.arraycopy(array, 0, arrayNew, 0, array.length);
        array = arrayNew;
    }

    /**
     * 數組刪除元素
     * @param index  刪除的位置
     */
    public int delete(int index) throws Exception {
        //判斷訪問下標是否超出範圍
        if(index<0 || index>=size){
            throw new IndexOutOfBoundsException("超出數組實際元素範圍!");
        }
        int deletedElement = array[index];
        //從左向右循環,逐個元素向左挪一位。
        for(int i=index; i<size-1; i++){
            array[i] = array[i+1];
        }
        size--;
        return deletedElement;
    }

    /**
     * 輸出數組
     */
    public void output(){
        for(int i=0; i<size; i++){
            System.out.println(array[i]);
        }
    }

    public static void main(String[] args) throws Exception {
        MyArray myArray = new MyArray(4);
        myArray.insert(0,3);
        myArray.insert(1,7);
        myArray.insert(2,9);
        myArray.insert(3,5);
        myArray.insert(1,6);
        myArray.insert(5,8);
        myArray.delete(3);
        myArray.output();
    }
}

        本篇博客中代碼來源於《漫畫算法》,應本書作者要求,加上本書公衆號《程序員小灰》二維碼。
在這裏插入圖片描述
        感興趣的朋友可以去購買正版實體書,確實不錯,非常適合小白入門。
在這裏插入圖片描述

總結

        數組的優勢:

        數組擁有非常高效的隨機訪問能力,只要給出下標,就可以用常量時間找到對應元素。有一種高效查找元素的算法叫作二分查找,就是利用了數組的這個優勢。

        數組的劣勢:

        數組的劣勢,體現在插入,刪除元素方面。由於數組元素連續緊密地存儲在內存中,插入、刪除元素都會導致大量元素被迫移動,影響效率。

        總的來說,數組所適合的是讀操作多,寫操作少的場景,下一節 我們要講解的鏈表則恰恰相反。

        如果以上過程中出現了任何的紕漏錯誤,煩請大佬們指正😅

        受益的朋友或對大數據技術感興趣的夥伴記得點贊關注支持一波🙏

        希望我們都能在學習的道路上越走越遠😉
在這裏插入圖片描述

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