数组(Array)
数组(Array) 是计算机科学中最基础的数据结构之一,它用连续的内存空间存储相同类型的元素,并通过**下标(索引)**快速访问元素。以下是关于数组的核心知识点:
一、基本概念
定义
- 数组是由相同数据类型的元素构成的集合,占用连续的内存空间。
- 元素通过**下标(索引)**访问,下标通常从0开始(如第1个元素的下标为0)。
存储结构
- 内存中,数组元素按顺序连续存放,每个元素占用固定大小的空间。
- 例如,整数数组
[10, 20, 30]在内存中的布局可能为:(假设每个整数占4字节,地址递增4)。内存地址 值 0x1000 10 0x1004 20 0x1008 30
维度
- 一维数组:线性排列(如
[1, 2, 3])。 - 多维数组:数组的数组(如二维数组可视为“矩阵”)。
- 一维数组:线性排列(如
二、数组的操作与复杂度
1. 访问元素
- 时间复杂度:O(1)(随机访问)。
- 通过下标直接计算内存地址:
address = base_address + index * element_size。 - 示例:访问数组
a[2],直接定位到内存地址base + 2*size。
2. 插入元素
- 时间复杂度:O(n)(最坏情况,需移动后续元素)。
- 示例:在数组
[1, 2, 3, 4]的下标1处插入5,需将后续元素后移:原数组:[1, 2, 3, 4] 插入后:[1, 5, 2, 3, 4] // 2、3、4后移
3. 删除元素
- 时间复杂度:O(n)(需移动后续元素填补空缺)。
- 示例:删除数组
[1, 5, 2, 3, 4]的下标1处元素,需将后续元素前移:原数组:[1, 5, 2, 3, 4] 删除后:[1, 2, 3, 4] // 2、3、4前移
4. 遍历数组
- 时间复杂度:O(n)(需访问每个元素一次)。
- 示例(Python):python
arr = [1, 2, 3, 4] for element in arr: print(element)
三、静态数组 vs 动态数组
1. 静态数组
- 特点:
- 大小在创建时固定,无法动态调整;
- 内存连续分配,空间利用率高。
- 缺点:可能导致空间浪费(如预留过大)或溢出(如数据超过容量)。
- 示例(C语言):c
int static_arr[5]; // 创建大小为5的静态数组
2. 动态数组
- 特点:
- 大小可动态调整(如Java的ArrayList、Python的list);
- 底层通常基于静态数组实现,当容量不足时自动扩容(如翻倍)。
- 扩容机制:
- 创建更大的新数组(如原容量的2倍);
- 将原数组元素复制到新数组;
- 释放原数组内存。
- 扩容时间复杂度:均摊O(1)(单次扩容代价高,但多次操作平均后接近O(1))。
- 示例(Python):python
dynamic_list = [] # 初始为空 dynamic_list.append(1) # 动态添加元素 dynamic_list.append(2)
四、多维数组
1. 二维数组(矩阵)
- 定义:由行和列构成的表格状结构,可视为“数组的数组”。
- 访问方式:
array[row][column]。 - 内存布局:
- 行优先存储:先存储第一行,再存储第二行,以此类推(如C、Python);
- 列优先存储:先存储第一列,再存储第二列(如Fortran)。
- 示例(Python):python
matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] print(matrix[1][2]) # 输出6(第2行第3列)
2. 多维数组
- 三维数组可视为“立方体”,四维及以上数组用于更复杂的数学模型。
- 访问方式:
array[i][j][k](三维示例)。
五、数组的应用场景
存储连续数据
- 如图像像素(二维数组)、音频采样数据(一维数组)。
实现其他数据结构
- 栈、队列、哈希表等可基于数组实现(如顺序栈)。
高效随机访问
- 适用于需要快速定位元素的场景(如数据库索引)。
算法设计
- 排序算法(如快速排序、归并排序)的主要操作对象;
- 动态规划中常用数组存储中间结果。
六、常见数组操作的代码示例
1. 创建与初始化
python
# 一维数组
arr1 = [1, 2, 3, 4]
# 二维数组(3x3矩阵)
arr2 = [[0 for _ in range(3)] for _ in range(3)]
# 等价于:[[0, 0, 0], [0, 0, 0], [0, 0, 0]]2. 插入元素
python
arr = [1, 2, 3, 4]
arr.insert(1, 5) # 在索引1处插入5
print(arr) # 输出:[1, 5, 2, 3, 4]3. 删除元素
python
arr = [1, 5, 2, 3, 4]
arr.pop(1) # 删除索引1处的元素
print(arr) # 输出:[1, 2, 3, 4]4. 遍历与修改
python
arr = [1, 2, 3, 4]
for i in range(len(arr)):
arr[i] *= 2 # 每个元素乘以2
print(arr) # 输出:[2, 4, 6, 8]七、数组的优缺点
| 优点 | 缺点 |
|---|---|
| 随机访问效率极高(O(1)) | 插入/删除效率低(O(n)) |
| 内存连续,空间利用率高 | 静态数组大小固定 |
| 实现简单 | 动态数组扩容有性能开销 |
八、面试高频问题
数组去重
- 问题:移除数组中的重复元素。
- 解法:排序后双指针遍历,或用哈希表(如Python的set)。
两数之和
- 问题:在数组中找到两个数的和等于目标值。
- 解法:哈希表记录已遍历元素,O(n)时间复杂度。
滑动窗口最大值
- 问题:给定滑动窗口,求每个窗口中的最大值。
- 解法:双端队列(维护窗口内的递减元素)。
螺旋矩阵
- 问题:按螺旋顺序遍历二维矩阵。
- 解法:模拟螺旋路径,逐层遍历。
数组是理解数据结构的基础,后续的栈、队列、哈希表等结构均基于数组实现。掌握数组的核心操作和复杂度分析是解决算法问题的关键。