这个问题还是前一阵子面试的时候遇到的,就是给你一个数字N,建立一个N×N的矩阵,元素有外层向内层递增,也就是:
1 2 3
8 9 4
7 6 5
这样的矩阵;当时做了一个多小时也没有弄出来,其实本来是一个很简单的东西,可能当时实在是脑子有些累了,因为面试要做一些笔试,还得应付考官的问题,实在是没有精力再去考虑那个算法,后来回来后我从网上也没有看到很好的算法,没办法,就自己憋吧,其实核心算法并不麻烦,仅仅是设置几个关键位置的标志,主要是思路清晰点就好了,后来我也没做出来,就放到那里了,昨天晚上突然心血来潮,决定把他搞出来,终于,搞定了,于是拿出来跟大家分享下,大家有什么好的算法也可要不吝赐教。。。。
#include<iostream>
using namespace std;
bool CreateMetrix(int *pMetrix,int n)
{
int i = 0, //数据元素
j = 0, //列号
k = 0;//行号
int iUp = 0,//上边界
iDown = n,//下边界
iLeft = 0,//左边界
iRight = n;//右边界
bool bRight = true,//左右填充方向
bDown = true;//上下填充方向
if (NULL == pMetrix)
{
return false;
}
memset(pMetrix,0,sizeof(int) * n*n);
//开始填充
for (i = 1; i <= n*n; i++)
{
//首先向右填充
if (bRight)
{
if (j < iRight)//还没有到达右边界
{
*(pMetrix + n * k + j) = i;
j++;
}
else
{
k++;//列号不变,增加行号,因为上面已经填充了对应行的列元素,故先将行号增加
if (k < iDown)//还没有到最底端
{
*(pMetrix + n * k + (j - 1)) = i;//此处的j是目前列号加1,因为上面的判断条件所致
}
else
{
iRight--;//右边界列号减1
iDown--;//下边界行号减1
k--;//行号减1
j--;//列号减1
bRight = false;//已经走完一个折线,接下来是向左填充了
}
}
}
if (!bRight)//向左填充
{
if (j > iLeft)//如果还没有到达左边界
{
j--;//在前面已经把第k行第j列元素填充了
*(pMetrix + n * k + j) = i;
}
else
{
k--;//第k行元素已经填充
if (k > iUp)//还没有到达最顶部
{
*(pMetrix + n * k + j) = i;
}
else
{
iLeft++;//左边界加1
iUp++;//上边界加1
k++;//k已经减过头了
j++;//j也见过头了
i--;//这时候这个数据没有被填充,所以回退一个
bRight = true;//下面又要向右填充了
}
}
}
}
return true;
}
void OutPutMetrix(int *Src, int n)
{
int t = 0;
for (int i = 0; i < n; i ++)
{
for (int j = 0; j < n; j++)
{
t = *(Src + n*i + j);
cout << "/t" << t;
}
cout << endl;
}
}
int main()
{
int *p = NULL;
int n = 2;
cout <<"输入矩阵的维度:" << endl;
cin >> n;
if (n > 0)
{
p = new int[n*n];
}else
{
cout << "输入数字有误!/n本程序不能处理,再见!" << endl;
return 0;
}
if (CreateMetrix(p,n))
{
OutPutMetrix(p, n);
}
else
{
cout << "处理中出现错误,很抱歉。。。" << endl;
}
delete p;
return 1;
}
函数直接就可以用,只要传递一个矩阵的指针和维度就ok了