数组
数组(Array)是最基础的线性数据结构,它把一组类型相同的元素存放在一段连续的内存中,通过下标可以直接计算出元素的地址,从而实现 $O(1)$ 的随机访问。
数组的特点
- 连续存储: 元素在内存中连续排列,对 CPU 缓存友好。
- 随机访问: 已知下标即可直接访问,时间复杂度 $O(1)$。
- 长度固定: Go 中
[N]T的长度N是类型的一部分,声明后不可改变。 - 值类型: Go 的数组是值类型,赋值和传参会复制整个数组。
基本操作
声明与初始化:
var a [3]int:长度为 3,元素为零值。a := [3]int{1, 2, 3}:声明并初始化。b := [...]int{1, 2, 3}:由初始值个数推断长度。
访问与修改:
a[i],下标越界会在编译期(常量下标)或运行时报错。遍历:
for i := 0; i < len(a); i++或for i, v := range a。多维数组:
[2][3]int表示 2 行 3 列的二维数组。
代码示例(Go语言实现)
go
package main
import "fmt"
// sum 计算数组元素之和(数组按值拷贝传入)
func sum(a [5]int) int {
total := 0
for _, v := range a {
total += v
}
return total
}
func main() {
// 声明并初始化
a := [5]int{3, 1, 4, 1, 5}
// 由初始值个数推断长度
b := [...]string{"Go", "C", "Python"}
// 修改元素
a[0] = 10
// 遍历
for i, v := range a {
fmt.Printf("a[%d] = %d\n", i, v)
}
// 二维数组
var matrix [2][3]int
for i := range matrix {
for j := range matrix[i] {
matrix[i][j] = i*3 + j
}
}
fmt.Println("matrix =", matrix)
fmt.Println("len(a) =", len(a), "sum =", sum(a))
fmt.Println("b =", b)
}运行输出:
text
a[0] = 10
a[1] = 1
a[2] = 4
a[3] = 1
a[4] = 5
matrix = [[0 1 2] [3 4 5]]
len(a) = 5 sum = 21
b = [Go C Python]数组与切片的关系
- 数组长度固定,是值类型;切片(slice)长度可变,是对底层数组的视图。
- 对数组取切片
a[1:3]得到的切片与原数组共享内存,修改切片会影响数组。 - 日常开发中更常使用切片,但切片本身离不开数组这块"底层的连续内存"。
复杂度分析
- 访问: $O(1)$,按下标直接寻址。
- 查找: $O(n)$,无序数组需要线性扫描。
- 插入/删除: 定长数组没有动态插入删除;若在中间腾位或收拢元素需要移动后续元素,代价为 $O(n)$。
总结
数组以连续内存换取了最快的随机访问速度,是切片、动态数组、哈希桶等许多结构的基础。在 Go 中数组是值类型且长度属于类型,因此通常以切片的形式使用数组语义。