蛇形矩阵问题

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运行结果如下:
在这里插入图片描述



六、总结

这种算法和以往的不同之处就是用了动态内存分配(如算法一),减少了内存浪费,如果嫌此方法麻烦,可以直接在开始定义一个二维数组(如算法二)。

  • 10
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值