【Java演示】什麼是數組?數據結構(二)

大家好,我是愛做夢的魚,我是一個大三的小菜雞,非常向往優秀,羨慕優秀的人,已拿兩個暑假offer,歡迎大家找我進行交流😂😂😂
這是我的博客地址:子浩的博客https://blog.csdn.net/weixin_43124279

專欄《兩週幹掉數據結構》

內容大部分摘自下《漫畫算法 小灰的算法之旅》,加了自己的一部分想法
System.arraycopy()會使我們對數組的操作變簡單,建議去看一下以下這篇文章
java的數組複製方法System.arraycopy()的使用說明

數組:隨機讀取,順序存儲

1. 讀取數據

int array = {1,2,3,4,5}
array[index]

2. 更新元素

int array = {1,2,3,4,5}
array[index]=newValue

數組讀取元素和更新元素的時間複雜度都是O(1) 。

3. 插入元素

==在介紹插入數組元素的操作之前,我們需要補充一個概念,那就是數組
的實際元素數量有可能小於數組的長度,這裏很重要。==例如下面的情形。
在這裏插入圖片描述
因此,插入數組元素的操作存在3種情況。

  1. 尾部插入
  2. 中間插入
  3. 超範圍插入

3.1. 尾部插入

尾部插入,是最簡單的情況,直接把插入的元素放在數組尾部的空閒位置即可,等同於更新元素的操作。
在這裏插入圖片描述

public void insert(int index, int element) {
        array[index] = element;
        size++;
}

3.2. 中間插入

中間插入,稍微複雜一些。由於數組的每一個元素都有其固定下標,所以不得不首先把插入位置及後面的元素向後移動,騰出地方,再把要插入的元素放到對應的數組位置上。在這裏插入圖片描述

/**
 * Created by IntelliJ IDEA.
 *
 * @Author: 張志浩  Zhang Zhihao
 * @Email: [email protected]
 * @Date: 2020/4/30
 * @Time: 19:20
 * @Version: 1.0
 */
public class MyArray3 {
    private static int aa;
    private int[] array;
    private int size;

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

    public static void main(String[] args) throws Exception {
        MyArray3 myArray3 = new MyArray3(10);
        // myArray2.insert(-1, 8); //超出數組實際元素範圍!
        // myArray2.insert(3, 8); //超出數組實際元素範圍!
        myArray3.insert(0, 3);
        myArray3.insert(1, 7);
        myArray3.insert(2, 9);
        myArray3.insert(3, 5);
        myArray3.insert(1, 6);
        myArray3.output();
    }

    /**
     * 數組插入元素
     *
     * @param index   插入的位置
     * @param element 插入的元素
     */
    public void insert(int index, int element) {
        //判斷訪問下標是否超出範圍
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException("超出數組實際元素範圍!");
        }

        //從右向左循環,逐個元素向右挪一位。
        for (int i = size - 1; i >= index; i--) {
            array[i + 1] = array[i];
        }
//        System.arraycopy(array, index, array, index + 1, size - index);

        //騰出的位置放入新元素
        array[index] = element;
        size++;
    }

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

該代碼不只是中間插入,其實考慮了尾部插入+中間插入(頭部插入算中間插入)
代碼中的成員變量size是數組實際元素的數量。

  1. 如果插入元素在數組尾部,傳入的下標參數index等於size;
  2. 如果插入元素在數組中間或頭部,則index小於size。
  3. 如果傳入的下標參數index大於size或小於0,則認爲是非法輸入,會直接拋出異常。

3.1. 超範圍輸入

假如現在有一個長度爲6的數組,已經裝滿了元素,這時還想插入一個新元素。
在這裏插入圖片描述
這就涉及數組的擴容了。可是數組的長度在創建時就已經確定了,無法像孫悟空的金箍棒那樣隨意變長或變短。這該如何是好呢?此時可以創建一個新數組,長度是舊數組的2倍,再把舊數組中的元素統統複製過去,這樣就實現了數組的擴容。
在這裏插入圖片描述

/**
 * Created by IntelliJ IDEA.
 *
 * @Author: 張志浩  Zhang Zhihao
 * @Email: [email protected]
 * @Date: 2020/4/30
 * @Time: 19:28
 * @Version: 1.0
 */
public class MyArray4 {
    private int[] array;
    private int size;

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

    public static void main(String[] args) throws Exception {
        MyArray4 myArray4 = new MyArray4(4);
        myArray4.insert(-1, 8); //超出數組實際元素範圍!
        myArray4.insert(3, 8); //超出數組實際元素範圍!
        myArray4.insert(0, 3);
        myArray4.insert(1, 7);
        myArray4.insert(2, 9);
        myArray4.insert(3, 5);
        myArray4.insert(1, 6);
        myArray4.insert(5, 8); //超出數組長度4
        myArray4.output();
    }

    /**
     * 數組插入元素
     *
     * @param index   插入的位置
     * @param element 插入的元素
     */
    public void insert(int index, int element) {
        //判斷訪問下標是否超出範圍
        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];
        }
//        System.arraycopy(array, index, array, index + 1, size - index);

        //騰出的位置放入新元素
        array[index] = element;
        size++;
    }

    /**
     * 數組擴容
     */
    public void resize() {
        int[] arrayNew = new int[array.length * 2];

        //從舊數組拷貝到新數組
        for (int i = 0; i < size; i++) {
            arrayNew[i] = array[i];
        }
//        System.arraycopy(array, 0, arrayNew, 0, array.length);

        array = arrayNew;
    }

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

4. 刪除元素

數組的刪除操作和插入操作的過程相反,如果刪除的元素位於數組中間,其後的元素都需要向前挪動1位。

在這裏插入圖片描述

/**
     * 數組刪除元素
     *
     * @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];
        }
//        System.arraycopy(array, index + 1, array, index, size - 1 - index);

        size--;
        return deletedElement;
    }

Java實現可擴展數組完整代碼(插入+刪除)

有同學私聊我想要能運行的插入加刪除的完整代碼

/**
 * Created by IntelliJ IDEA.
 *
 * @Author: 張志浩  Zhang Zhihao
 * @Email: [email protected]
 * @Date: 2020/4/30
 * @Time: 19:28
 * @Version: 1.0
 */
public class MyArray {

    private int[] array;
    private int size;

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

    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();
    }

    /**
     * 數組插入元素
     *
     * @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];
        }
//        System.arraycopy(array, index, array, index + 1, size - index);

        //騰出的位置放入新元素
        array[index] = element;
        size++;
    }

    /**
     * 數組擴容
     */
    public void resize() {
        int[] arrayNew = new int[array.length * 2];

        //從舊數組拷貝到新數組
        for (int i = 0; i < size; i++) {
            arrayNew[i] = array[i];
        }
//        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];
        }
//        System.arraycopy(array, index + 1, array, index, size - 1 - index);

        size--;
        return deletedElement;
    }

    /**
     * 輸出數組
     */
    public void output() {
        for (int i = 0; i < size; i++) {
            System.out.print(array[i] + " ");
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章