C语言实现蛇形矩阵问题
一、问题
浅浅的谈一下数据结构中的蛇形矩阵的问题:
编写算法,将自然数1 ~ n2按“蛇形”填入 n2 矩阵中。例(1 ~ 42)如下图所示(用程序实现)。
二、存在的问题
首先,在解决这个问题时,很多人会想到用一个二维数组,但是二维数组必须事先指定行数和列数(因为数组是以静态的方式分配内存),会有很严重的内存浪费,所以要以动态的方式分配内存(malloc函数分配内存)。
三、思路
1. 创建一个动态的n * n矩阵。
2. 这种蛇形矩阵是按照次对角线进行数字的填充,但是每次沿次对角线填的数字的个数和方向是变化的。左上部分要填的数字的个数每次都在加1,右下部分要填的数字的个数每次都在减1。每次沿次对角线填完之后换一次方向,如下图:
所以要分成左上和右下两部分进行填充,左上部分的最大值为n*(n+1) / 2,右下部分的最大值为 n*n。
3. 输出二维数组
四、算法
算法一(动态内存分配)
#include<stdio.h>
#include<malloc.h>
int ** Create_Array(int n) //创建动态二维数组
{
int i, ** p;
p = (int **)malloc(n * sizeof(int *));
for(i=0;i<n;i++)
{
p[i] = (int *)malloc(n * sizeof(int));
}
return p;
}
int ** Upper_Left(int **p, int * c, int n ,int * s) //左上部分
{
int i,j;
while(*c <= n*(n+1)/2)
{
for(i=*s,j=0;i>=0,j<=*s;i--,j++)
{
if(*s%2 != 0)
p[i][j] = (*c)++;
else
p[j][i] = (*c)++;
}
(*s)++;
}
return p;
}
int ** Low_Right(int **p,int c, int n, int s) //右下部分
{
int i,j;
int x = 1;
while(c <= n*n)
{
for(i=x,j=s-1;i<=s-1,j>=x;i++,j--)
{
if(n%2 == 0)
{
if(x%2 != 0)
p[i][j] = c++;
else
p[j][i] = c++;
}
else
{
if(x%2 == 0)
p[i][j] = c++;
else
p[j][i] = c++;
}
}
x++;
}
return p;
}
void Print_Array(int ** p, int n) //输出
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%-3d ",p[i][j]);
printf("\n");
}
}
int main()
{
int n,**p;
int c=1,s=0;
printf("请输入矩阵的阶数 n = ");
scanf("%d",&n);
p = Create_Array(n);
p = Upper_Left(p, &c, n ,&s);
p = Low_Right( p, c, n, s);
Print_Array(p,n);
return 0;
}
算法二(静态内存分配)
#include<stdio.h>
void Upper_Left(int p[][100], int * c, int n ,int * s) //左上部分
{
int i,j;
while(*c <= n*(n+1)/2)
{
for(i=*s,j=0;i>=0,j<=*s;i--,j++)
{
if(*s%2 != 0)
p[i][j] = (*c)++;
else
p[j][i] = (*c)++;
}
(*s)++;
}
}
void Low_Right(int p[][100],int c, int n, int s) //右下部分
{
int i,j;
int x = 1;
while(c <= n*n)
{
for(i=x,j=s-1;i<=s-1,j>=x;i++,j--)
{
if(n%2 == 0)
{
if(x%2 != 0)
p[i][j] = c++;
else
p[j][i] = c++;
}
else
{
if(x%2 == 0)
p[i][j] = c++;
else
p[j][i] = c++;
}
}
x++;
}
}
void Print_Array(int p[][100], int n) //输出
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%-3d ",p[i][j]);
printf("\n");
}
}
int main()
{
int n,c=1,s=0;
int a[100][100];
printf("请输入矩阵的阶数 n = ");
scanf("%d",&n);
Upper_Left(a, &c, n ,&s);
Low_Right( a, c, n, s);
Print_Array(a,n);
return 0;
}
五、运行结果
输入4运行结果如下:
六、总结
这种算法和以往的不同之处就是用了动态内存分配(如算法一),减少了内存浪费,如果嫌此方法麻烦,可以直接在开始定义一个二维数组(如算法二)。