一张图像表示成NxN的矩阵,图像中每个像素是4个字节,写一个函数把图像旋转90度。 你能原地进行操作吗?(即不开辟额外的存储空间)
这个题第一感觉就是一次交换矩阵的元素:
比如 3*3 矩阵
1 2 3
4 5 6
7 8 9
先处理第一行,一次逆时针旋转四个元素,下面是二次做的
3 2 9 3 6 9
4 5 6 2 5 8
1 8 7 1 4 7
第一次 第二次
如果是5*5的矩阵
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
一下是处理第一行后的变化
5 2 3 4 25
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
1 22 23 24 21
第1次
5 10 3 4 25
6 7 8 9 24
11 12 13 14 15
2 17 18 19 20
1 22 23 16 21
第2次
5 10 15 4 25
6 7 8 9 24
3 12 13 14 23
2 17 18 19 20
1 22 11 16 21
第3次
5 10 15 20 25
4 7 8 9 24
3 12 13 14 23
2 17 18 19 22
1 6 11 16 21
第4次
第一行处理之后
剩下没处理的是一个3*3的矩阵
7 8 9
12 12 13
17 18 19
在按照3*3处理最后就得到结果
5 10 15 20 25
4 9 14 19 24
3 8 13 18 23
2 7 12 17 22
1 6 11 16 21
但在写代码时,这种想法编码比较麻烦,要处理数组下标计算,很麻烦。
下面介绍另一种方法
我们看 4*4的矩阵
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
我们线交换主对角线两边的元素:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
然后在交换第i行和第n-i-1行的元素就得到结果
4 8 12 16
3 7 11 15
2 6 10 14
1 5 9 13
下面是代码:
#define N 4
void swap(int& vLeft, int& vRight)
{
int Temp = vLeft;
vLeft = vRight;
vRight = Temp;
}
//逆时针旋转
void rotate_matrix(int vMat[N][N])
{
//先交换主对角线两边的元素, 如果是顺时针旋转,交换副对角线两边的元素
for (int i=0; i<N; ++i)
{
for (int k=i+1; k<N; ++k)
{
swap(vMat[i][k], vMat[k][i]);
}
}
//在交换i行与N-i-1行的元素
for (int i=0; i<N/2; ++i)
{
for (int k=0; k<N; ++k)
{
swap(vMat[i][k], vMat[N-i-1][k]);
}
}
}
void print_matrix(int vMat[N][N])
{
for (int i=0; i<N; ++i)
{
for (int k=0; k<N; ++k)
{
printf("%3d ", vMat[i][k]);
}
printf("\n");
}
}
int main()
{
int a[N][N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
print_matrix(a); printf("\n");
rotate_matrix(a);
print_matrix(a);
system("pause");
return 0;
}矩阵旋转90度(keep it up),布布扣,bubuko.com
原文地址:http://blog.csdn.net/xiaoliangsky/article/details/38589689