数据结构与算法——矩阵

引言

数据结构与算法中,矩阵是一个重要的概念,它既是数据结构的一种,也是算法中经常需要处理的对象。以下是对矩阵的详细介绍:

一、矩阵的定义

矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,它是一个二维的数据结构,由行和列组成,通常用来表示二维的数据集合。在数学中,矩阵最早来自于方程组的系数及常数所构成的方阵,这一概念由19世纪英国数学家凯利首先提出。在数据结构中,矩阵主要讨论如何在节省存储空间的前提下,正确高效地运算矩阵。

二、矩阵的特征

  • 二维数组:矩阵也可以看作是一个二维数组,即"数组的数组"。
  • 元素类型:矩阵的元素可以是数字、字符、布尔值等类型。
  • 非线性结构:虽然矩阵表面上看似不符合线性表的特征(如首结点不唯一、尾结点不唯一、中间结点有两个直接前驱和两个直接后驱),但实质上,我们可以把每行(或每列)数据看成一个整体,作为一个数据元素,那么矩阵就符合线性表的特征,只是每个数据元素的类型又是一个线性表。

三、矩阵的存储方式

  • 按行优先顺序存储:即将数组元素按行排序,第i+1行的第一个元素紧接在第i行的最后一个元素的后面。
  • 按列优先顺序存储:即将数组元素按列排序,第j+1列的第一个元素紧接在第j列的最后一个元素的后面。

四、矩阵的运算

矩阵的运算包括加法、减法、乘法、转置等。

  • 加法与减法:矩阵的加法和减法要求两个矩阵的维数相同,即行数和列数都必须相等,然后对应位置的元素进行加或减运算。
  • 乘法:矩阵的乘法不是简单的对应位置元素相乘,而是按照矩阵乘法规则进行计算,即第一个矩阵的行向量与第二个矩阵的列向量进行点积运算。
  • 转置:矩阵的转置是将矩阵的行和列互换,即原矩阵的第i行第j列元素在转置矩阵中变为第j行第i列元素。

五、矩阵的应用

矩阵在计算机科学中有着广泛的应用,比如在机器学习和人工智能领域中,矩阵被用来表示数据集合和模型参数,进行数据处理和计算。在图形学中,矩阵被用来表示图像的像素值和进行图像处理操作。在网络编程中,矩阵也被用来表示网络拓扑结构和进行数据传输。此外,在物理学、工程学、经济学等多个领域,矩阵也有着重要的应用。

六、特殊矩阵

  • 对称矩阵:在一个n阶方阵中,如果满足aij=aji(1≤i,j≤n),则称该矩阵为对称矩阵。对称矩阵关于主对角线对称,因此可以压缩存储,节省存储空间。
  • 稀疏矩阵:如果矩阵中数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律,则称该矩阵为稀疏矩阵。稀疏矩阵常使用三元组存储法,即存储非零元的同时,存储该元素所对应的行下标和列下标。

经典例题

1. 螺旋矩阵

题目描述

给定一个正整数n,生成一个包含1到n^2所有元素,且元素按顺时针顺序螺旋排列的n x n正方形矩阵。

解题思路

  • 使用四个变量表示当前遍历的上下左右边界。

  • 按照右、下、左、上的顺序遍历矩阵,每次遍历到边界时更新边界值。

  • 当所有元素都被遍历时,结束循环。

    #include <vector>
    using namespace std;

    vector<vector<int>> generateMatrix(int n) {
    vector<vector<int>> matrix(n, vector<int>(n, 0));
    int num = 1, left = 0, right = n - 1, top = 0, bottom = n - 1;

      while (num <= n * n) {  
          // Traverse right  
          for (int i = left; i <= right && num <= n * n; ++i) {  
              matrix[top][i] = num++;  
          }  
          top++;  
    
          // Traverse down  
          for (int i = top; i <= bottom && num <= n * n; ++i) {  
              matrix[i][right] = num++;  
          }  
          right--;  
    
          // If not the last element  
          if (top <= bottom) {  
              // Traverse left  
              for (int i = right; i >= left && num <= n * n; --i) {  
                  matrix[bottom][i] = num++;  
              }  
              bottom--;  
          }  
    
          if (left <= right) {  
              // Traverse up  
              for (int i = bottom; i >= top && num <= n * n; --i) {  
                  matrix[i][left] = num++;  
              }  
              left++;  
          }  
      }  
        
      return matrix;  
    

    }

2. 搜索二维矩阵

题目描述

编写一个高效的算法来搜索m x n矩阵matrix中的一个目标值target。该矩阵具有以下特性:每行的元素从左到右升序排列;每列的元素从上到下升序排列。

解题思路

  • 从矩阵的右上角或左下角开始搜索。

  • 如果当前元素等于目标值,则返回true。

  • 如果当前元素大于目标值,向左移动一列。

  • 如果当前元素小于目标值,向下移动一行。

    #include <vector>
    using namespace std;

    bool searchMatrix(vector<vector<int>>& matrix, int target) {
    if (matrix.empty() || matrix[0].empty()) return false;
    int rows = matrix.size(), cols = matrix[0].size();
    int row = 0, col = cols - 1;

      while (row < rows && col >= 0) {  
          if (matrix[row][col] == target) return true;  
          else if (matrix[row][col] < target) row++;  
          else col--;  
      }  
        
      return false;  
    

    }

3. 旋转图像

题目描述

给定一个n x n的二维矩阵matrix表示一个图像。请你将图像顺时针旋转90度。你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。

解题思路

  • 先沿主对角线翻转矩阵。

  • 再按行翻转矩阵的每一行。

    #include <vector>
    using namespace std;

    void rotate(vector<vector<int>>& matrix) {
    int n = matrix.size();

      // Flip along the diagonal  
      for (int i = 0; i < n; ++i) {  
          for (int j = i; j < n; ++j) {  
              swap(matrix[i][j], matrix[j][i]);  
          }  
      }  
        
      // Flip each row  
      for (int i = 0; i < n; ++i) {  
          for (int j = 0; j < n / 2; ++j
    
相关推荐
搬砖的小码农_Sky3 分钟前
C语言:数组
c语言·数据结构
Swift社区1 小时前
LeetCode - #139 单词拆分
算法·leetcode·职场和发展
Kent_J_Truman2 小时前
greater<>() 、less<>()及运算符 < 重载在排序和堆中的使用
算法
先鱼鲨生2 小时前
数据结构——栈、队列
数据结构
一念之坤2 小时前
零基础学Python之数据结构 -- 01篇
数据结构·python
IT 青年2 小时前
数据结构 (1)基本概念和术语
数据结构·算法
熬夜学编程的小王2 小时前
【初阶数据结构篇】双向链表的实现(赋源码)
数据结构·c++·链表·双向链表
Dong雨2 小时前
力扣hot100-->栈/单调栈
算法·leetcode·职场和发展
SoraLuna3 小时前
「Mac玩转仓颉内测版24」基础篇4 - 浮点类型详解
开发语言·算法·macos·cangjie
liujjjiyun3 小时前
小R的随机播放顺序
数据结构·c++·算法