之前介绍的是由外向内的螺旋矩阵,现在再来个由内向外的例子:
7 8 9 10
6 1 2 11
5 4 3 12
16 15 14 13
主要的思路是先确定中心(即起点),然后开始旋转扩大,方向的控制依旧是使用dir=(dir+1)%4来获得,有必要解释一下:
switch(dir) { case 0:rj=j+1;ri=i;gj=j;gi=i-1;break; case 1:rj=j;ri=i+1;gj=j+1;gi=i;break; case 2:rj=j-1;ri=i;gj=j;gi=i+1;break; case 3:rj=j;ri=i-1;gj=j-1;gi=i;break; default:break; }
----------------------------------> J轴
| 7 8 9 10 由左到右等价为:j=j+1;i值不变
| 6 1 2 11 由上至下等价为:j值不变;i=i+1
| 5 4 3 12 由右到左等价为:j=j-1;i值不变
| 16 15 14 13 由下至上等价位:j值不变;i=i-1
V
I轴
阐述完了这些,我们就能理解下面代码的思路了
case 0:rj=j+1;ri=i;gj=j;gi=i-1;break;
要么沿着dir=0(由左到右)这个方向前进,要么我们沿着上一个方向(dir=3,即由下至上)前进。程序用到了递归,也很简短,供参考。
另外还有一些其他思路:
·)通过由外向内的螺旋矩阵的变换得到由内向外的矩阵;
·)运用数学分析直接确定每个位置的数值。
下面是全部的代码样例
#include <stdio.h> #include <...> #define SIZE 10 int a[SIZE][SIZE]; int main(void) { // memset(a, 0, sizeof(a)); a[(N-1)/2][(N-1)/2]=1; SpiralMatrix((N-1)/2,(N-1)/2,0,2,N*N); //print spiral matrix for(int i=0;i<SIZE;i++) { for(int j=0;j<SIZE;j++) printf("%3d ",a[i][j]); printf(" "); } return 0; } void SpiralMatrix(int i,int j,int dir,int start,int final) { int ri,rj,gi,gj; if(start>final) return; switch(dir) { case 0:rj=j+1;ri=i;gj=j;gi=i-1;break; case 1:rj=j;ri=i+1;gj=j+1;gi=i;break; case 2:rj=j-1;ri=i;gj=j;gi=i+1;break; case 3:rj=j;ri=i-1;gj=j-1;gi=i;break; default:break; } //通过该条件判断是沿着现有的方向继续前进还是开始转向 if(a[ri][rj]==0) { a[ri][rj]=start; SpiralMatrix(ri,rj,(dir+1)%4,start+1,final); } else { a[gi][gj]=start; SpiralMatrix(gi,gj,dir,start+1,final); } }