1. 概述

在本文中,我们将学习一种遍历矩阵元素的算法,该算法按照正方形螺旋(Square Spiral)的顺序访问矩阵中的每个元素。这种遍历方式常用于图像处理、游戏地图扫描、数据压缩等场景。

2. 什么是螺旋遍历?

螺旋遍历指的是从矩阵的一个点出发,按顺时针或逆时针方向,像画圈一样逐步访问矩阵中的每个元素。与数学上的连续螺旋曲线不同,矩阵螺旋是离散且逐步推进的。

比如下面是一个 3x3 矩阵的顺时针螺旋遍历顺序:

1  2  3
8  9  4
7  6  5

也可以从中心向外扩展,形成反向螺旋:

9  2  3
8  1  4
7  6  5

3. 非方阵的处理

当矩阵不是方阵时(行数 ≠ 列数),我们依然可以采用类似的螺旋逻辑进行遍历。通常做法是:

  • 将原矩阵“扩展”为一个方阵(大小为 max(N, M))
  • 遍历整个方阵,跳过那些超出原矩阵范围的元素

例如一个 3x5 的矩阵,扩展后可按如下顺序遍历:

15  9  2  3 10
14  8  1  4 11
13  7  6  5 12

4. 从中心向外螺旋遍历

我们以矩阵中心为起点,向外螺旋遍历至边界。为了实现这个过程,我们需要维护:

  • 当前坐标 (x, y),相对于中心点
  • 移动方向 (dx, dy),每次在拐角处旋转方向

✅ 顺时针螺旋算法

public static void spiralClockwise(int N, int M, int[][] A) {
    int x = 0, y = 0;
    int dx = 0, dy = -1;

    for (int i = 0; i < Math.pow(Math.max(N, M), 2); i++) {
        // 判断当前坐标是否在原矩阵范围内
        if (-N / 2 < x && x <= N / 2 && -M / 2 < y && y <= M / 2) {
            // 访问 A[x][y],这里可以替换成你的处理逻辑
            System.out.print(A[x + N / 2][y + M / 2] + " ");
        }

        // 判断是否需要转向
        if (x == y || (x == -y && x < 0) || (x == 1 - y && x > 0)) {
            // 旋转方向
            int temp = dx;
            dx = -dy;
            dy = temp;
        }

        x += dx;
        y += dy;
    }
}

✅ 逆时针螺旋算法

public static void spiralCounterClockwise(int N, int M, int[][] A) {
    int x = 0, y = 0;
    int dx = 0, dy = 1;

    for (int i = 0; i < Math.pow(Math.max(N, M), 2); i++) {
        if (-N / 2 < x && x <= N / 2 && -M / 2 < y && y <= M / 2) {
            System.out.print(A[x + N / 2][y + M / 2] + " ");
        }

        if (x == -y || (x == y && x > 0) || (x == -1 + y && x < 0)) {
            // 旋转方向
            int temp = dx;
            dx = dy;
            dy = -temp;
        }

        x += dx;
        y += dy;
    }
}

⚠️ 注意:在访问 A[x][y] 时,需要根据矩阵的实际索引进行偏移调整,比如加上 N/2 和 M/2。

5. 从角点向中心螺旋遍历

如果我们希望从角点开始向中心螺旋遍历,只需要将从中心向外遍历的路径反转即可。

例如,对一个 5x7 的矩阵,从中心向外遍历得到的顺序是:

1 2 3 ...

反转后,从角点向中心遍历的顺序是:

... 3 2 1

这种做法在需要“由外向内”扫描的场景中非常有用,比如图像滤波、地图寻路等。

6. 总结

在本文中,我们介绍了如何按螺旋顺序访问矩阵中的元素,包括:

  • 什么是矩阵的螺旋遍历
  • 如何处理非方阵
  • 从中心向外的顺时针和逆时针螺旋算法
  • 从角点向中心的反向螺旋实现方式

这些算法在图像处理、AI路径规划、图形渲染等领域都有广泛应用。掌握其实现原理,有助于你更好地应对复杂的数据结构问题。


原始标题:Looping in a Spiral