题目:给定一个数n,螺旋输出一个 n*n 矩阵,其中元素为1到n*n。
比如,给定 3或4,所要输出的矩阵样式为:
1 | 2 | 3 |
8 | 9 | 4 |
7 | 6 | 5 |
1 | 2 | 3 | 4 |
12 | 13 | 14 | 5 |
11 | 16 | 15 | 6 |
10 | 9 | 8 | 7 |
这一题我一直找不到好的方法来解决,只能是先将矩阵构造出来,然后再打印。可能需要考虑的细节比较多,尤其涉及到行列的变换,需要很细心。代码如下:
/*!
思想:先构造出矩阵,再将其输出
算法有两层循环,第一层控制圈数,第二层控制方向
1) n*n矩阵最多能有(n+1)/2圈
2) 共有四个方向,东西方向控制列的变化,东增西减;
南北方向控制行的变化,南增北减
3) 时间复杂度o(n^2)
*/
首先定义一个方向的枚举变量
//定义四个方向的枚举变量
typedef enum DIRECTION
{
EastDir =1,
SourthDir =1<<1,
WestDir =1<<2,
NorthDir =1<<3,
} DIRECTION;
//矩阵打印函数的声明
void prinrMatrix(int **a,int n);
//矩阵构造及输出函数
int SpiralMatrix(int n)
{
if (n <1) {
return -1;
}
//动态构建n*n矩阵
int **a = (int **)malloc(n *sizeof(int *));
for(int i=0; i<n; i++)
{
a[i]=(int *)malloc(sizeof(int) * n);
}
//初始化矩阵
for (int i=0; i<n; i++) {
for(int j=0; j<n;j++) {
a[i][j] =0;
}
}
int loop =0; //记录圈数,最外面是第0圈,n*n个元素最多有(n+1)/2圈
DIRECTION direc = EastDir; //记录行走方向
int value =1; //数组元素值,从1开始
int row =0, colum =0; //数组行列
while (loop < (n+1)/2 )
{
while (direc <=NorthDir)
{
switch (direc)
{
case EastDir:
{
while (colum < n - loop)
{
a[row][colum++] = value++;
}
row++;
colum--;
direc <<=1;
}
break;
case SourthDir:
{
while (row < n - loop)
{
a[row++][colum] = value++;
}
colum--;
row--;
direc <<=1;
}
break;
case WestDir:
{
while (colum >= loop)
{
a[row][colum--] = value++;
}
row--;
colum++;
direc <<=1;
}
break;
case NorthDir:
{
while (row > loop)
{
a[row--][colum] = value++;
}
colum++;
row++;
direc <<=1;
}
break;
default:
return -1;
}
}
direc =EastDir; //下一圈仍然从东开始
loop++;
}
prinrMatrix(a,n);
free(a);
return 0;
}
//定义打印函数
void prinrMatrix(int **a,int n)
{
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
printf("%2d ",a[i][j]);
}
printf("\n");
}
}
SpiralMatrix(5);
即可打印出相应的矩阵