【数据结构】数组
数组
数组(Array),由相同数据类型的元素(element)的集合组成的数据结构,分配一块连续的内存来存储。
初始化
初始化一个数组(不给定初始值):
1 | // 创建一个名为arr的整数数组 |
初始化一个数组(给定初始值):
1 | // 创建一个名为nums的整数数组,并初始化数组元素 |
访问元素
在数组中访问元素非常高效,我们可以在 𝑂(1)
时间内随机访问数组中的任意一个元素。
1 | // 定义一个方法randomAccess,该方法接收一个整数数组nums作为参数 |
插入元素
数组是一种存储固定大小元素的数据结构。数组的元素在内存中是连续存储的,也就是说,它们是"紧挨着的"。当你想在数组中间插入一个元素时,必须将该元素之后的所有元素都向后移动一位,再将待插入的元素插入到中间位置。
1 | // 在数组 nums 的索引 index 处插入元素 num |
删除元素
与插入元素类似,如果你想删除数组中某一位置的元素,需要将后面的元素都向前移动一位。
删除元素后,原先末尾的元素就已经“无意义”了,因此不用特意修改。
1 | // 删除数组 nums 中索引为 index 处的元素 |
遍历数组
在Java中,遍历数组即可以通过索引来遍历,也可以通过for-each
方式来遍历。
1 | // 遍历数组 |
查找元素
在数组中查找特定的元素,可以通过一层循环,遍历数组元素,在每轮循环中判断当前数组元素是否为待查找的元素。若匹配,则输出对应索引,否则返回-1,代表查无此元素。
1 | // 在数组 nums 中查找指定元素 target |
数组扩容
在Java中,数组的长度是固定不可变的,一旦数组被创建后,其长度就不能更改。如果你需要扩容数组,通常的做法是创建一个新数组,并将原数组中的元素复制到新数组中。
举个例子,比如这里给定了一个旧数组 oldArray
,然后创建了一个新数组 newArray
(长度是旧数组长度的两倍),最后,将旧数组的元素复制到新数组中。
1 | // 定义旧数组 oldArray,包含元素 1, 2, 3, 4, 5 |
当前,你也可以通过System.arraycopy
方法将一个数组的内容复制到另一个数组(适用于大规模数据的复制)
1 | int[] oldArray = {1, 2, 3, 4, 5}; |
或者,也可以使用 Arrays.copyOf
方法来复制数组元素:
1 | int[] oldArray = {1, 2, 3, 4, 5}; |
数组的优点和局限性
数组是一种在编程中常用的数据结构,具有一些优点和一些局限性。
优点:
- 快速访问: 数组中的元素通过索引直接访问,这使得对元素的访问速度非常快,支持随机访问,时间复杂度为
O(1)
。 - 内存连续: 数组中的元素在内存中是连续存储的,这有助于缓存性能的提升,空间效率高。
- 简单易用: 数组的使用非常简单,适合存储和访问一组相同类型的元素。
局限性:
- 固定大小: 数组在创建时需要指定固定的大小,这导致了无法动态调整数组的长度。如果需要动态大小的数据结构,可能需要使用其他集合类。
- 插入和删除开销大: 在数组中插入或删除元素通常需要移动其他元素,这导致了较大的时间复杂度(
O(n)
)。 - 浪费空间: 如果数组的大小超过实际需要的大小,会导致内存浪费。反之,如果数组太小,可能需要频繁地进行扩容操作。
- 不适合频繁的查找和删除: 数组适用于快速访问,但对于频繁的查找和删除操作,可能不是最佳选择。
动态数组
在Java中,ArrayList 是一种动态数组,属于 java.util
包。
ArrayList
与内置数组的区别在于,数组的大小无法修改(如果要向数组添加或删除元素,必须创建一个新数组)。而ArrayList
可以随时添加和删除元素。当 ArrayList
的元素数量超过其当前容量时,ArrayList
会自动增加其容量。
也就是ArrayList帮你实现好了扩容,底层通过创建一个新的数组,将原数组的元素复制到新数组中来实现的。默认情况下,扩容时会将容量翻1.5倍。
ArrayList
是使用泛型实现的,可以存储任意类型的对象。在创建 ArrayList
时,可以指定元素的类型。
下面是 ArrayList
的常见用法:
- 创建ArrayList对象:
1 | import java.util.ArrayList; |
- 添加元素:
1 | cars.add("Volvo"); |
- 访问元素:
1 | String car = cars.get(0); |
- 修改元素:
1 | cars.set(0, "Opel"); |
- 删除元素:
1 | cars.remove(0); |
- 清空
ArrayList
:
1 | cars.clear(); |
- 获取
ArrayList
大小:
1 | int size = cars.size(); |
- 遍历
ArrayList
:
使用for循环:
1 | for (int i = 0; i < cars.size(); i++) { |
或使用for-each
循环:
1 | for (String car : cars) { |
- 排序
ArrayList
:
使用Collections.sort()
方法:
1 | Collections.sort(cars); // 对字符串进行排序 |