数据结构:矩阵

数据结构:矩阵

  • 矩阵是由 m 行 n 列元素排列成的二维矩形数组,是线性代数和计算机科学中基础的数据结构。在编程中,矩阵通常用于表示二维数据(如图像像素、邻接矩阵)、线性变换、方程组等场景。
  • 资料:https://pan.quark.cn/s/43d906ddfa1bhttps://pan.quark.cn/s/90ad8fba8347https://pan.quark.cn/s/d9d72152d3cf

一、矩阵的定义与表示

1. 数学定义

一个 m×n 矩阵 (m 行 n 列)可表示为:
A=[a11a12...a1na21a22...a2n⋮⋮⋱⋮am1am2...amn] A = \begin{bmatrix} a_{11} & a_{12} & \dots & a_{1n} \\ a_{21} & a_{22} & \dots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \dots & a_{mn} \end{bmatrix} A= a11a21⋮am1a12a22⋮am2......⋱...a1na2n⋮amn

其中 aija_{ij}aij 表示矩阵第 iii 行第 jjj 列的元素,矩阵的维度记为 m×n

2. 编程中的存储方式

在计算机中,矩阵的存储主要有两种方式:

  • 二维数组(行优先存储) :最常用的方式,如 Python 的 list[list]、Java 的 int[][],按行顺序存储元素,访问 a[i][j] 的时间复杂度为 O(1)O(1)O(1)。
  • 一维数组映射 :将二维矩阵映射到一维数组,通过公式 index = i * n + j(行优先)或 index = j * m + i(列优先)计算元素位置,适合底层内存优化。

二、矩阵的核心分类

根据元素分布和维度特征,矩阵可分为以下常见类型:

  1. 方阵 :行数和列数相等(m=n)的矩阵,如 3×3 矩阵。方阵可定义对角线元素 (aiia_{ii}aii)、上三角矩阵 (对角线下方元素全为 0)、下三角矩阵(对角线上方元素全为 0)。
  2. 单位矩阵 :一种特殊的方阵,对角线元素全为 1,其余元素全为 0,记为 III。例如 3×3 单位矩阵:
    I3=[100010001] I_3 = \begin{bmatrix}1&0&0\\0&1&0\\0&0&1\end{bmatrix} I3= 100010001
  3. 零矩阵 :所有元素均为 0 的矩阵,记为 OOO。
  4. 对称矩阵 :满足 aij=ajia_{ij}=a_{ji}aij=aji 的方阵,其转置等于自身(AT=AA^T=AAT=A)。
  5. 稀疏矩阵 :大部分元素为 0 的矩阵,通常用三元组(行号, 列号, 值)十字链表存储,节省空间。

三、矩阵的核心操作

1. 基础操作

操作 描述 时间复杂度
访问元素 获取第 i 行第 j 列的元素 O(1)O(1)O(1)
矩阵转置 将矩阵的行和列互换,得到 ATA^TAT,满足 AT[i][j]=A[j][i]A^T[i][j] = A[j][i]AT[i][j]=A[j][i] O(m×n)O(m×n)O(m×n)
矩阵加法 两个同维度矩阵对应位置元素相加,要求 AAA 和 BBB 均为 m×n 矩阵 O(m×n)O(m×n)O(m×n)
标量乘法 矩阵中所有元素乘以一个常数 k O(m×n)O(m×n)O(m×n)

2. 矩阵乘法

矩阵乘法是矩阵的核心操作,仅当第一个矩阵的列数等于第二个矩阵的行数时可乘

  • 若 AAA 是 m×pm×pm×p 矩阵,BBB 是 p×np×np×n 矩阵,则乘积 C=A×BC=A×BC=A×B 是 m×nm×nm×n 矩阵,其中:
    C[i][j]=∑k=0p−1A[i][k]×B[k][j] C[i][j] = \sum_{k=0}^{p-1} A[i][k] × B[k][j] C[i][j]=k=0∑p−1A[i][k]×B[k][j]
  • 时间复杂度:O(m×p×n)O(m×p×n)O(m×p×n),是算法优化的重点(如 Strassen 算法可优化至 O(n2.81)O(n^{2.81})O(n2.81))。

3. 特殊操作

  • 矩阵求逆 :仅方阵可逆时存在逆矩阵 A−1A^{-1}A−1,满足 A×A−1=IA×A^{-1}=IA×A−1=I,常用于解线性方程组。
  • 行列式计算 :仅适用于方阵,是衡量矩阵是否可逆的重要指标,记为 det(A)det(A)det(A)。

四、矩阵的实现示例(Python)

python 复制代码
class Matrix:
    def __init__(self, data):
        """初始化矩阵,data为二维列表"""
        self.data = data
        self.rows = len(data)
        self.cols = len(data[0]) if self.rows > 0 else 0

    def __str__(self):
        """矩阵的字符串表示"""
        return '\n'.join([' '.join(map(str, row)) for row in self.data])

    def transpose(self):
        """矩阵转置"""
        transposed = [[self.data[j][i] for j in range(self.rows)] for i in range(self.cols)]
        return Matrix(transposed)

    def add(self, other):
        """矩阵加法,要求维度相同"""
        if self.rows != other.rows or self.cols != other.cols:
            raise ValueError("矩阵维度不匹配,无法相加")
        result = []
        for i in range(self.rows):
            row = [self.data[i][j] + other.data[i][j] for j in range(self.cols)]
            result.append(row)
        return Matrix(result)

    def multiply(self, other):
        """矩阵乘法,要求self.cols == other.rows"""
        if self.cols != other.rows:
            raise ValueError("矩阵维度不匹配,无法相乘")
        result = []
        for i in range(self.rows):
            row = []
            for j in range(other.cols):
                # 计算C[i][j] = sum(A[i][k] * B[k][j])
                val = sum(self.data[i][k] * other.data[k][j] for k in range(self.cols))
                row.append(val)
            result.append(row)
        return Matrix(result)

# 使用示例
if __name__ == "__main__":
    # 初始化两个矩阵
    A = Matrix([[1, 2, 3], [4, 5, 6]])  # 2×3矩阵
    B = Matrix([[7, 8], [9, 10], [11, 12]])  # 3×2矩阵
    C = Matrix([[1, 2], [3, 4]])  # 2×2矩阵

    print("矩阵A:")
    print(A)
    print("\n矩阵A的转置:")
    print(A.transpose())

    print("\n矩阵C + C:")
    print(C.add(C))

    print("\n矩阵A × B:")
    print(A.multiply(B))

五、矩阵的典型应用

  1. 图的存储:用邻接矩阵表示图的顶点关系,如无权图用 0/1 表示边的存在,加权图用权重值表示。
  2. 图像处理:图像的每个像素对应矩阵的一个元素,矩阵的变换(如旋转、缩放)可实现图像的几何变换。
  3. 线性代数计算:解线性方程组、特征值分析、线性变换(如旋转矩阵、投影矩阵)。
  4. 动态规划优化:如 Floyd-Warshall 算法用矩阵存储任意两点间的最短路径。
  5. 机器学习:神经网络的权重参数、卷积核均以矩阵形式存储,矩阵乘法是前向传播的核心计算。

六、稀疏矩阵的优化存储

对于稀疏矩阵(大部分元素为 0),直接用二维数组存储会浪费大量空间,常用以下优化方式:

  1. 三元组存储 :用列表存储所有非零元素的 (行号, 列号, 值),例如矩阵 [[0,2,0],[3,0,0],[0,0,5]] 可存储为 [(0,1,2), (1,0,3), (2,2,5)]
  2. 十字链表:用链表同时按行和列存储非零元素,适合频繁插入/删除非零元素的场景。
相关推荐
旺仔小拳头..3 小时前
数据结构(一)———线性表之顺序表、单向链表
数据结构·算法
xiaoxue..3 小时前
哨兵节点与快慢指针解决链表算法难题
前端·javascript·数据结构·算法·链表
拉姆哥的小屋3 小时前
从400维向量到160000维矩阵:基于深度学习的火焰参数预测系统全解析
开发语言·人工智能·python·深度学习·线性代数·算法·矩阵
lxh01133 小时前
最长公共子序列
前端·数据结构
小龙报4 小时前
【算法通关指南:基础算法篇】高精度专题:一篇破除超数运算问题
c语言·数据结构·c++·算法·链表·贪心算法·visual studio
Yupureki4 小时前
《算法竞赛从入门到国奖》算法基础:入门篇-双指针
c语言·开发语言·数据结构·c++·算法·visual studio
风筝在晴天搁浅4 小时前
hot100 128.最长连续序列
数据结构·哈希
LYFlied4 小时前
【每日算法】LeetCode148. 排序链表
前端·数据结构·算法·leetcode·链表
努力努力再努力wz4 小时前
【Linux网络系列】:网络+网络编程(UDPsocket+TCPsocket)
java·linux·c语言·开发语言·数据结构·c++·centos