最基本的数据结构数组

134 阅读3分钟

数组的重要性

学习的任何一门编程语言,有了一定编程语法基础后,之后学习第一篇内容基本上都是数组。对每一门编程语言来说都是重要的数组结构之一,只是不同语言对数组的实现及处理不尽相同。既然数组那么重要,那么来看下java语言是怎么实现数组,及应用。

什么是数组

1、数组(Array)是有序的元素序列。若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为。用于区分数组的各个元素的数字编号称为下标。数组是在中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。这些有序排列的同类数据元素的集合称为数组。定义来源

2、根据上面的定义可以知道数组有一下特点:

  • 数组是相同元素的集合及数组中存储的数据类型是一样的。
  • 有序的元素序列及数组中存储的数据是有先后顺序的,它们在内存中按照先后顺序连续存放在一起
  • 数组的长度一旦初始化后是固定不变的
  • 数组元素用整个数组的名字和它自己在数组中的顺序位置来表示,例如,a[0]表示名字为a的数组中的第一个元素,a[1]代表数组a的第二个元素,以此类推。

数组在java中体现

1、定义数组:

// 方式一:
dataType[] arrayRefVar = new dataType[arraySize];
// 方式二:
dataType[] arrayRefVar = {value0, value1, ..., valuek};

2、 数组的使用

public class TestArray {
    public static void main(String[] args) {
        // 数组大小
        int size = 10;
        // 定义数组
        double[] myList = new double[size];
        myList[0] = 5.6;
        myList[1] = 4.5;
        myList[2] = 3.3;
        myList[3] = 13.2;
        myList[4] = 4.0;
        myList[5] = 34.33;
        myList[6] = 34.0;
        myList[7] = 45.45;
        myList[8] = 99.993;
        myList[9] = 11123;
        // 计算所有元素的总和
        double total = 0;
        for (int i = 0; i < size; i++) {
            total += myList[i];
        }
        System.out.println("总和为: " + total);
    }
}

以上就是日常使用数组的定义及使用方式。

数组数组的增删改查

  • 查询:根据数组的特点,可以直接使用索引来定义数组中需要的元素,并返回。

  • 新增:

    如图:

image.png

  • 修改: 将传入的索引对应元素赋值传入的值。

  • 删除

    如图:

image.png

  • 数组类代码实现(其他一些扩展方法)

package com.chou.datastructure.array;

/**
 * @ClassName ArrayStructure
 * @Description 数组
 * @Author Chou
 * @Date 2021/8/28 23:28
 * @Version 1.0
 */

public class Array<E> {

    private int size;
    private E[] data;

    /**
     * 初始化构造函数
     */
    public Array() {
        this(10);
    }

    /**
     * 初始化数组容量大小构造函数
     *
     * @param capacity
     */
    public Array(int capacity) {
        data = (E[]) new Object[capacity];
        size = 0;
    }


    /**
     * 获取数组的大小
     *
     * @return
     */
    public int getSize() {
        return this.size;
    }

    /**
     * 获取数据的容量
     *
     * @return
     */
    public int getCapacity() {
        return data.length;
    }

    /**
     * 判断输出是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return getSize() == 0;
    }

    /**
     * 在数组末尾添加元素
     *
     * @param element
     */
    public void addLast(E element) {
        add(size, element);
    }

    /**
     * 在数组的开始位置添加一个元素
     *
     * @param element
     */
    public void addFirst(E element) {
        add(0, element);
    }


    /**
     * 在任意index位置添加元素
     *
     * @param index
     * @param element 4,5,3,2,1,6
     */
    public void add(int index, E element) {
        if (index < 0 || index > size) {
            throw new RuntimeException("Add element is failed,Required index >=0 and index =< size");
        }
        if (index == getCapacity()) {
            //todo 扩容
            throw new RuntimeException("Add failed,this Array is full");
        }
        for (int i = size - 1; i >= index; i--) {
            data[i + 1] = data[i];
        }
        data[index] = element;
        size++;
    }

    /**
     * 返回给定元素的索引值
     *
     * @param element
     * @return
     */
    public int search(E element) {
        for (int i = 0; i < size; i++) {
            if (data[i] == element) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 移除数组中的第一个元素
     *
     * @return 返回被移除的元素
     */
    public E removeFirst() {
        return remove(0);
    }

    /**
     * 移除数组的最后一个元素
     *
     * @return
     */
    public E removeLast() {
        return remove(size - 1);
    }

    /**
     * 移除数组中的index位置上元素
     *
     * @param index 索引值
     * @return 返回被移除的元素
     */
    public E remove(int index) {
        // 校验index的合法性
        if (isEmpty()) {
            throw new IllegalStateException("Remove() is failed,Array is empty!");
        }
        if (index < 0 || index > size) {
            throw new IllegalStateException("Remove() is failed,the index must to great than zero and less than size");
        }
        E oldValue = data[index];
        for (int i = index; i < size; i++) {
            data[i] = data[i + 1];
        }
        size--;
        return oldValue;
    }

    /**
     * 根据索引获取数组中元素
     *
     * @param index
     * @return
     */
    public E get(int index) {
        // 校验index是否合法
        if (index < 0 || index > size) {
            throw new RuntimeException("Get element is Failed,Required index >=0 and index < data.length");
        }
        return data[index];
    }

    /**
     * 获取数组中第一个元素
     *
     * @return
     */
    public E getFirst() {
        return get(0);
    }

    /**
     * 获取数据中最后一个元素
     *
     * @return
     */
    public E getLast() {
        return get(size - 1);
    }

    /**
     * 更新索引位 index 的值
     *
     * @param index
     * @param element
     */
    public void set(int index, E element) {
        // 校验index是否合法
        if (index < 0 || index > getCapacity()) {
            throw new RuntimeException("Get element is Failed,Required index >=0 and index < data.length");
        }
        data[index] = element;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        String arrInfo = String.format("Array capacity = %d size = %d", getCapacity(), getSize());
        System.out.println(arrInfo);
        sb.append("[");
        for (int i = 0; i < this.size; i++) {
            sb.append(data[i]);
            if (i != size - 1) {
                sb.append(",");
            }
        }
        sb.append("]");
        return sb.toString();
    }
}

数组的扩容

根据数组的定义我们知道,数组在初始化后长度是固定不变的,所以并不完全满足日常需求的一些开发。接下来看下对数组的扩容

/**
 * 在任意index位置添加元素
 *
 * @param index
 * @param element 4,5,3,2,1,6
 */
public void add(int index, E element) {

    if (index < 0 || index > size) {
        throw new RuntimeException("Add element is failed,Required index >=0 and index =< size");
    }

    if (index == getCapacity()) {
        expandCapacity(getCapacity()*2);
        /*throw new RuntimeException("Add failed,this Array is full");*/
    }

    for (int i = size - 1; i >= index; i--) {
        data[i + 1] = data[i];
    }
    data[index] = element;
    size++;
}

/**
 * 扩容
 * @param newSize
 */
private void expandCapacity(int newSize){
    E newArray[] = (E[]) new Object[newSize];
    //循环原有的数组放到新数组中
    for (int i = 0; i < data.length; i++) {
        newArray[i] = data[i];
    }
    data = newArray;
}

/**
 * 扩容
 * 使用java内部api扩容
 */
private void reSize(){
    E newArray[] = (E[]) new Object[data.length * 2];
    System.arraycopy(data,0,newArray,0,data.length);
    data = newArray;
}

数组中增删改查时间复杂度分析

1、查询

O(1){O(1)}

2、更新

O(1){O(1)}

3、删除

  • 在任意index删除一个element: O(n){O(n)}
  • 在数组尾部或者首部删除一个element: O(1){O(1)}

4、新增

  • 在任意index 新增一个element: O(n){O(n)}
  • 在数组尾部或者首部新增一个element: O(1){O(1)}

根据对复杂的分析数组适用于的场景是查找。

今天的数据结构就到了这里了,文章中有出入的地方请各位多多指教。