Skip to content

数组 ​

数组(Array)是最基础的线性数据结构,它把一组类型相同的元素存放在一段连续的内存中,通过下标可以直接计算出元素的地址,从而实现 $O(1)$ 的随机访问。

数组的特点 ​

  1. 连续存储: 元素在内存中连续排列,对 CPU 缓存友好。
  2. 随机访问: 已知下标即可直接访问,时间复杂度 $O(1)$。
  3. 长度固定: Go 中 [N]T 的长度 N 是类型的一部分,声明后不可改变。
  4. 值类型: Go 的数组是值类型,赋值和传参会复制整个数组。

基本操作 ​

  1. 声明与初始化:

    • var a [3]int:长度为 3,元素为零值。
    • a := [3]int{1, 2, 3}:声明并初始化。
    • b := [...]int{1, 2, 3}:由初始值个数推断长度。
  2. 访问与修改: a[i],下标越界会在编译期(常量下标)或运行时报错。

  3. 遍历: for i := 0; i < len(a); i++ 或 for i, v := range a。

  4. 多维数组: [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 中数组是值类型且长度属于类型,因此通常以切片的形式使用数组语义。

Hello Golang