数组基础
外观
数组基础[编辑 | 编辑源代码]
数组(Array)是最基础且广泛使用的线性数据结构,它在内存中用连续的空间存储相同类型的元素集合,并通过从0开始的数字索引快速访问任意元素。几乎所有编程语言都原生支持数组。
核心特性[编辑 | 编辑源代码]
数组的三大核心特性使其成为高效的数据容器:
- 固定大小:创建时需指定长度(部分语言支持动态数组)
- 连续内存:元素在物理内存中相邻存储
- 随机访问:通过索引可在O(1)时间复杂度直接访问元素
数学表示为:,其中n为数组长度
基本操作[编辑 | 编辑源代码]
声明与初始化[编辑 | 编辑源代码]
不同语言的数组声明方式:
# Python列表(实际为动态数组)
arr = [10, 20, 30, 40]
// Java静态数组
int[] arr = new int[]{1, 2, 3};
访问元素[编辑 | 编辑源代码]
通过索引访问(时间复杂度O(1)):
// JavaScript示例
let colors = ['red', 'green', 'blue'];
console.log(colors[1]); // 输出"green"
修改元素[编辑 | 编辑源代码]
直接通过索引赋值:
// C语言示例
int nums[3] = {5, 10, 15};
nums[0] = 8; // 数组变为[8, 10, 15]
遍历数组[编辑 | 编辑源代码]
常见遍历方式对比:
方式 | 示例 | 适用场景 |
---|---|---|
for循环 | for(int i=0; i<length; i++) {
cout << arr[i];
}
|
需要索引时 |
foreach | for item in arr:
print(item)
|
仅需元素值 |
内存原理[编辑 | 编辑源代码]
数组的物理存储采用连续内存块,假设:
- 每个元素占4字节
- 数组起始地址为1000
- 访问arr[2]的计算过程:
解析失败 (语法错误): {\displaystyle \text{地址} = \text{基地址} + \text{索引} \times \text{元素大小} \\ = 1000 + 2 \times 4 = 1008 }
多维数组[编辑 | 编辑源代码]
二维数组可视为"数组的数组",如矩阵:
// Java二维数组
int[][] matrix = {
{1, 2, 3},
{4, 5, 6}
};
System.out.println(matrix[1][2]); // 输出6
内存布局(行优先存储):
实际应用案例[编辑 | 编辑源代码]
案例1:图像处理 灰度图像的像素矩阵用二维数组存储:
# 800x600分辨率的图像
pixels = [[0]*800 for _ in range(600)]
pixels[50][100] = 255 # 设置(x100,y50)处像素为白色
案例2:游戏开发 背包物品栏使用数组管理:
// Unity C#示例
Item[] inventory = new Item[10];
inventory[0] = new Sword(); // 第一格放置剑
inventory[1] = new Potion(); // 第二格放置药水
复杂度分析[编辑 | 编辑源代码]
操作 | 时间复杂度 | 说明 |
---|---|---|
访问 | O(1) | 直接通过索引计算地址 |
搜索 | O(n) | 无序数组需线性查找 |
插入 | O(n) | 需移动后续元素 |
删除 | O(n) | 需移动后续元素 |
常见问题[编辑 | 编辑源代码]
页面模块:Message box/ambox.css没有内容。
数组越界访问是初学者最易犯的错误 |
int arr[3] = {1,2,3};
cout << arr[3]; // 未定义行为!合法索引是0-2
进阶思考[编辑 | 编辑源代码]
- 动态数组(如C++的vector)如何实现自动扩容?
- 为什么数组索引通常从0开始而不是1?
- 稀疏数组如何优化存储空间?