首页 > 代码库 > 矩阵旋转90度(keep it up)
矩阵旋转90度(keep it up)
一张图像表示成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; }