数据结构---数组

1. 简介

        数组(Array)是一种线性数据结构,用于存储多个元素,这些元素在内存中是连续存储的。数组的每个元素都可以通过索引访问,通常索引是从0开始的。

数组的特点:

固定大小:一旦创建,数组的大小就固定了,无法动态增加或减少元素数量。你需要在创建时确定数组的长度。

存储类型一致:数组中的所有元素必须是同一数据类型。

高效的随机访问:可以通过索引直接访问数组中的元素,时间复杂度为O(1)。

内存连续:数组的元素在内存中是连续存储的,这使得它非常适合于需要频繁随机访问的场景。

2. 分类

2.1 一维数组

一维数组是最常用的数组,其他很多数据结构的变种也都是从一维数组来的。例如 HashMap 的拉链寻址结构,ThreadLocal 的开放寻址结构,都是从一维数组上实现的。

HashMap结构:

ThreadLocal结构:数组大小根据元素个数确定(比元素个数大)

2.2 二维数组

二维数组是数组的数组。它可以看作是一个矩阵,具有行和列的结构。

arr[0][0] = 5,arr[1][0] = 78。二维数组在日常开发中不太常见,在一些算法逻辑与数学计算中倒是可以使用。

3. 实例

数组的基本操作:

  1. 访问元素:通过索引访问数组元素,如 arr[i]

  2. 插入元素:插入元素通常需要移动数组中部分元素来腾出空间,这种操作的时间复杂度是O(n)。

  3. 删除元素:删除元素时,通常需要移动数组中的其他元素来填补空缺,时间复杂度也是O(n)。

  4. 更新元素:直接通过索引更新数组中的元素,时间复杂度为O(1)。

基于数组的基本操作实现一个简单的类ArrayList:

import java.util.Arrays;

public class SimpleArrayList {
    private Object[] arr;  // 存储元素的数组
    private int size;      // 当前数组中存储的元素个数

    // 默认容量
    private static final int DEFAULT_CAPACITY = 10;

    // 构造函数
    public SimpleArrayList() {
        arr = new Object[DEFAULT_CAPACITY];
        size = 0;
    }

    // 添加元素
    public void add(Object element) {
        // 如果数组满了,扩容
        if (size == arr.length) {
            resize();
        }
        arr[size++] = element;
    }

    // 删除指定索引的元素
    public void remove(int index) {
        if (index < 0 || index >= size) {
            System.out.println("索引越界!");
            return;
        }
        
        // 删除元素后,将后面的元素前移
        for (int i = index; i < size - 1; i++) {
            arr[i] = arr[i + 1];
        }
        arr[--size] = null;  // 更新 size,并将最后一个元素置为 null
    }

    // 获取指定索引的元素
    public Object get(int index) {
        if (index < 0 || index >= size) {
            System.out.println("索引越界!");
            return null;
        }
        return arr[index];
    }

    // 查找元素的索引
    public int indexOf(Object element) {
        for (int i = 0; i < size; i++) {
            if (arr[i].equals(element)) {
                return i;
            }
        }
        return -1;  // 未找到元素
    }

    // 扩容数组
    private void resize() {
        int newCapacity = arr.length * 2;
        arr = Arrays.copyOf(arr, newCapacity);
    }

    // 打印数组元素
    public void printList() {
        System.out.print("ArrayList: ");
        for (int i = 0; i < size; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    // 获取当前元素个数
    public int size() {
        return size;
    }
}

该实例实现了如下功能:

添加元素 (add())

获取元素 (get())

删除元素 (remove())

查找元素的索引 (indexOf())

扩容(当数组满时,自动扩展数组)

打印当前数组 (printList())

测试:

public class ArrayListTest{
    public static void main(String[] args) {
        SimpleArrayList list = new SimpleArrayList();

        // 添加元素
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        list.add("Hello");

        // 打印数组
        list.printList();  // 输出: ArrayList: 10 20 30 40 Hello

        // 获取指定索引的元素
        System.out.println("索引2的元素: " + list.get(2));  // 输出: 30

        // 查找元素的索引
        System.out.println("元素30的索引: " + list.indexOf(30));  // 输出: 2
        System.out.println("元素100的索引: " + list.indexOf(100));  // 输出: -1

        // 删除元素
        list.remove(2);
        list.printList();  // 输出: ArrayList: 10 20 40 Hello

        // 删除不存在的索引
        list.remove(10);  // 输出: 索引越界!

        // 打印当前大小
        System.out.println("当前数组大小: " + list.size());  // 输出: 4
    } 
}

这个实例可以做进一步的优化和拓展:

动态缩小数组:目前只是增加了容量,没有减少容量。可以添加一个“收缩”功能,比如当数组的使用量低于一定比例时,减少数组的大小。

线程安全:如果希望这个实现是线程安全的,可以考虑使用 synchronized 关键字,或者使用 java.util.concurrent 中的线程安全集合类。

泛型支持:当前实现使用了 Object[] 来存储所有元素,如果想要支持更严格的类型检查,可以使用泛型类来代替 Object

4. 二维数组拓展

一个简单的二维数组相加示例,打开新世界大门。

public class MatrixAddition {
    public static void main(String[] args) {
        int[][] matrix1 = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        
        int[][] matrix2 = {
            {9, 8, 7},
            {6, 5, 4},
            {3, 2, 1}
        };
        
        int rows = matrix1.length;  // 行数
        int columns = matrix1[0].length;  // 列数
        
        int[][] result = new int[rows][columns];
        
        // 矩阵相加
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                result[i][j] = matrix1[i][j] + matrix2[i][j];
            }
        }
        
        // 打印结果矩阵
        System.out.println("矩阵相加的结果:");
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                System.out.print(result[i][j] + " ");
            }
            System.out.println();
        }
    }
}

二维数组 是数组的数组,适合存储和处理矩阵或表格数据。

创建方式 可以是静态初始化(定义时就指定所有值)或者动态初始化(先声明大小再赋值)。

遍历二维数组 通常使用嵌套 for 循环来处理每个元素。

可以使用 不规则数组(即锯齿状数组)来处理列数不等的情况。

不积跬步,无以至千里 --- xiaokai

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值