螺旋矩阵的实现以及代码优化
螺旋矩阵是指一个呈螺旋状的矩阵,如下图所示,就是一个边长为5(笔者个人称一个数字边长为1)的螺旋矩阵。
算法思想
1.首先,读者可以先自行画出边长为3,4,5的螺旋矩阵观察。不难得出可以将每四个指向箭头定义成一个圈。
每个圈都是从左到右–从上到下–从右到左–从下到上递增1。因此,找出每个圈的起始位置,依次往后赋值即可完成此算法。
2.第一个圈的第一个数必为1。因此可以用它作为计算其它圈的起始数字。总结规律可以得到:
后一个圈的起始数字 = 前一个圈的起始数字 + 4(前一个圈的边长 -1);*
算法的Java代码实现
package com.yuexiang;
import java.util.Scanner;
public class SnakeArray {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要打印的矩阵边长:");
int n = scanner.nextInt(); //获取边长
int[][] a = new int[n][n]; //定义一个二维数组(矩阵)
int tempN = n; //保存初始边长
int num = 0; //定义num初始下标
int rowfirst = 1; //定义第一个圈第一个数,固定为1
int i,j; //循环控制
while(n>0){ //当边长大于0,继续赋值
a[num][num]=rowfirst; //给当前圈的初始位置赋值
if (n>1){
for (i=num,j=num+1;j<n+num;j++){ //自左向右
a[i][j]=a[num][num]+j-num;
}
for (i=num+1,j=num+n-1;i<n+num;i++){ //自上向下
a[i][j]=a[i-1][j]+1;
}
for (i=num+n-1,j=num+n-2;j>=num;j--){ //自右向左
a[i][j]=a[i][j+1]+1;
}
for (i=num+n-2,j=num;i>=num+1;i--){ //自下向上
a[i][j]=a[i+1][j]+1;
}
}else {
break;
}
rowfirst = rowfirst+4*(n-1); //计算下一圈的初始数字
n=n-2; //每完成一圈,边长减2
num++; //初始下标自增1
}
for (i=0;i<tempN;i++){ //打印矩阵
for (j=0;j<tempN;j++){
System.out.print(a[i][j]+" ");
}
System.out.println();
}
}
}
上面的算法虽然实现了功能,但是定义与过程过于繁杂。
下面进行代码优化
int a[][] = new int[n][n];
int value = 1;
int i=0,j=0;
for (int m=0;m<n/2+n%2;m++)
{
for(j=m,i=m;j<(n-m);j++) //自左向右
{
a[i][j]=value++;
}
for(j--,i++;i<(n-m);i++) //自上向下
{
a[i][j]=value++;
}
for(j--,i--;j>=m;j--) //自右向左
{
a[i][j]=value++;
}
for(i--,j++;i>m;i--) //自下向上
{
a[i][j]=value++;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
System.out.print(a[i][j]+" ");
}
System.out.println();
}
两相对比,可见第二个代码定义更加清晰,赋值过程更加明了。代码可读性也更高。
我们在学习算法时,一定要在写出程序后继续思考写出的算法是否有需要改进的地方,是否能更加简明的实现。
就说笔者的这第二段程序代码,也并不是最简单的实现,还能够继续优化。思考一下吧~