项目背景详细介绍
在算法学习与 C++ 基础训练中,矩阵类问题始终占据着非常重要的位置。
其中,环形矩阵(也称螺旋矩阵、蛇形矩阵)填充问题,几乎是所有算法课程、面试、竞赛中的“常青题”,例如:
LeetCode 螺旋矩阵
剑指 Offer 顺时针打印矩阵
各类笔试中的二维数组操作题
该类问题的特点是:
看似简单
实现细节多
边界条件复杂
非常容易写错
而一旦你真正掌握了环形矩阵的填充思路,你会发现:
所有二维遍历问题都有统一模型
“控制边界”是核心思想
算法思维与工程代码高度统一
在实际工程与教学中,该问题具有极高价值:
训练逻辑思维能力
强化数组 / vector 使用
锻炼边界条件控制能力
为更复杂图像处理、网格算法打基础
因此,本项目的目标是:
用一套清晰、稳定、可复用的 C++ 实现方案,完整讲解环形矩阵填充算法
并且做到:
思路清晰
代码可直接运行
适合博客讲解与课堂演示
项目需求详细介绍
1. 功能需求
使用 C++ 填充 N × N 的环形矩阵
支持顺时针填充
支持逆时针填充(扩展)
数值从 1 连续递增
正确处理奇偶维度
2. 技术要求
使用
std::vector存储矩阵不依赖任何第三方库
算法复杂度为 O(N²)
代码结构清晰、可读性强
3. 教学与工程要求
明确“边界收缩”思想
每一层(环)逻辑清晰
避免重复填充
可轻松改造为打印 / 遍历算法
相关技术详细介绍
1. 什么是环形矩阵
环形矩阵是指:
按照一圈一圈(从外到内)的方式,对二维矩阵进行遍历或填充
典型形式包括:
顺时针螺旋
逆时针螺旋
2. 核心思想:边界控制
整个算法的核心只有一个:
使用四个边界变量,逐步向内收缩
通常使用:
top:上边界bottom:下边界left:左边界right:右边界
3. 时间与空间复杂度
时间复杂度:
O(N²)空间复杂度:
O(N²)(用于存储矩阵)
实现思路详细介绍
本项目采用最经典、最稳定的边界收缩法,实现流程如下:
初始化矩阵
初始化四个边界
在
top <= bottom && left <= right条件下循环每一轮填充一“环”:
从左到右
从上到下
从右到左
从下到上
每完成一条边,收缩对应边界
该方法:
不依赖复杂判断
适用于任意 N
是所有螺旋矩阵问题的通用模板
完整实现代码
/**************************************************** * File: SpiralMatrix.h ****************************************************/ #pragma once #include <vector> class SpiralMatrix { public: static std::vector<std::vector<int>> fillClockwise(int n); static std::vector<std::vector<int>> fillCounterClockwise(int n); }; /**************************************************** * File: SpiralMatrix.cpp ****************************************************/ #include "SpiralMatrix.h" std::vector<std::vector<int>> SpiralMatrix::fillClockwise(int n) { std::vector<std::vector<int>> matrix(n, std::vector<int>(n, 0)); int top = 0, bottom = n - 1; int left = 0, right = n - 1; int value = 1; while (top <= bottom && left <= right) { // 从左到右 for (int col = left; col <= right; col++) matrix[top][col] = value++; top++; // 从上到下 for (int row = top; row <= bottom; row++) matrix[row][right] = value++; right--; // 从右到左 if (top <= bottom) { for (int col = right; col >= left; col--) matrix[bottom][col] = value++; bottom--; } // 从下到上 if (left <= right) { for (int row = bottom; row >= top; row--) matrix[row][left] = value++; left++; } } return matrix; } std::vector<std::vector<int>> SpiralMatrix::fillCounterClockwise(int n) { std::vector<std::vector<int>> matrix(n, std::vector<int>(n, 0)); int top = 0, bottom = n - 1; int left = 0, right = n - 1; int value = 1; while (top <= bottom && left <= right) { // 从上到下 for (int row = top; row <= bottom; row++) matrix[row][left] = value++; left++; // 从左到右 for (int col = left; col <= right; col++) matrix[bottom][col] = value++; bottom--; // 从下到上 if (left <= right) { for (int row = bottom; row >= top; row--) matrix[row][right] = value++; right--; } // 从右到左 if (top <= bottom) { for (int col = right; col >= left; col--) matrix[top][col] = value++; top++; } } return matrix; } /**************************************************** * File: main.cpp ****************************************************/ #include "SpiralMatrix.h" #include <iostream> void printMatrix(const std::vector<std::vector<int>>& matrix) { for (const auto& row : matrix) { for (int v : row) std::cout << v << "\t"; std::cout << std::endl; } } int main() { int n = 5; std::cout << "顺时针填充:" << std::endl; auto clockwise = SpiralMatrix::fillClockwise(n); printMatrix(clockwise); std::cout << "\n逆时针填充:" << std::endl; auto counter = SpiralMatrix::fillCounterClockwise(n); printMatrix(counter); return 0; }代码详细解读(仅解读方法作用)
fillClockwise
按照顺时针方向,使用边界收缩法填充矩阵。
fillCounterClockwise
按照逆时针方向填充矩阵,逻辑与顺时针对称。
边界变量(top / bottom / left / right)
用于控制当前“环”的上下左右范围。
printMatrix
辅助函数,用于输出二维矩阵。
main
演示不同方向的环形矩阵填充效果。
项目详细总结
通过本项目,你可以扎实掌握:
二维矩阵遍历的通用模型
边界控制在算法中的重要性
如何写出不乱、不漏、不重复的矩阵代码
将抽象算法转化为清晰工程实现的能力
这是一个非常经典、回报率极高的 C++ 算法训练项目。
项目常见问题及解答
Q1:为什么需要判断top <= bottom?
A:防止奇数阶矩阵中间元素被重复填充。
Q2:可以扩展成 M×N 吗?
A:可以,只需分别维护行列边界。
Q3:这是最优解吗?
A:时间复杂度已达到理论最优。
扩展方向与性能优化
支持 M × N 非方阵
改为“打印而非填充”
改造为 ZigZag / 波浪矩阵
图像像素环形遍历
与 BFS / DFS 网格算法结合