前言
在很多题目抽象化后的模型里会用到矩形的旋转,这时候如果知道了矩形旋转的方法,便可以在编码环节快速的实现。这里是实现简易的旋转,所以不涉及旋转任意角度的公式计算,只有旋转90,180,270等的方法。
一、顺时针旋转九十度
给定 matrix = [ [1,2,3], [4,5,6], [7,8,9] ] 原地旋转输入矩阵,使其变为: [ [7,4,1], [8,5,2], [9,6,3] ]
#include#include #define SIZE 3//矩形数组的长宽大小 void swap(int* a, int* b)//交换赋进来的两个变量 { int temp = (*b); (*b) = (*a); (*a) = temp; } void rotate(int matrix[][SIZE], int matrixSize)//通过翻转操作去实现旋转 { //水平翻转 for (int i = 0; i < matrixSize / 2; i++) { for (int j = 0; j < matrixSize; j++) { swap(&matrix[i][j], &matrix[matrixSize - 1 - i][j]); } } //主对角线翻转 for (int i = 0; i < matrixSize; i++)//对角线翻转 { for (int j = 0; j < i; j++) { swap(&matrix[i][j], &matrix[j][i]); } } } int main() { int matrix[SIZE][SIZE] = //定义初始的数组 { {1,2,3}, {4,5,6}, {7,8,9} }; rotate(matrix, SIZE);//旋转 for (int i = 0; i < SIZE; i++)//打印出结果 { for (int j = 0; j < SIZE; j++) { printf("%d ", matrix[i][j]); } printf("n"); } system("pause"); return 0; }
这里的顺时针九十度翻转,通过两次不同的对折方式实现,分别是水平对折和主对角线对折。
那么对于所有九十度和一百八十度的矩形旋转,我们都可以通过两次对折来实现。具体的实现原理经过简单的手绘推导便能得出了,对于这种简易的旋转我们更多的是应该去大致的记住其实现方式,而对于更随机且无规律的旋转角度的操作才真正需要我们去理解其原理。
二、旋转180度#include#include #define SIZE 3//矩形数组的长宽大小 void swap(int* a, int* b)//交换赋进来的两个变量 { int temp = (*b); (*b) = (*a); (*a) = temp; } void rotate(int matrix[][SIZE], int matrixSize)//通过翻转操作去实现旋转 { //左右翻转 for (int i = 0; i < matrixSize; i++) { for (int j = 0; j < matrixSize / 2; j++) { swap(&matrix[i][j], &matrix[i][matrixSize - j - 1]); } } //水平翻转 for (int i = 0; i < matrixSize / 2; i++) { for (int j = 0; j < matrixSize; j++) { swap(&matrix[i][j], &matrix[matrixSize - 1 - i][j]); } } } int main() { int matrix[SIZE][SIZE] = //定义初始的数组 { {1,2,3}, {4,5,6}, {7,8,9} }; rotate(matrix, SIZE);//旋转 for (int i = 0; i < SIZE; i++)//打印出结果 { for (int j = 0; j < SIZE; j++) { printf("%d ", matrix[i][j]); } printf("n"); } system("pause"); return 0; }
同样,这里也是用了两种翻转方式实现了180度旋转,分别是左右翻转和上下翻转。
三、逆时针旋转90度#include#include #define SIZE 3//矩形数组的长宽大小 void swap(int* a, int* b)//交换赋进来的两个变量 { int temp = (*b); (*b) = (*a); (*a) = temp; } void rotate(int matrix[][SIZE], int matrixSize)//通过翻转操作去实现旋转 { //左右翻转 for (int i = 0; i < matrixSize; i++) { for (int j = 0; j < matrixSize / 2; j++) { swap(&matrix[i][j], &matrix[i][matrixSize - j - 1]); } } //主对角线翻转 for (int i = 0; i < matrixSize; i++)//对角线翻转 { for (int j = 0; j < i; j++) { swap(&matrix[i][j], &matrix[j][i]); } } } int main() { int matrix[SIZE][SIZE] = //定义初始的数组 { {1,2,3}, {4,5,6}, {7,8,9} }; rotate(matrix, SIZE);//旋转 for (int i = 0; i < SIZE; i++)//打印出结果 { for (int j = 0; j < SIZE; j++) { printf("%d ", matrix[i][j]); } printf("n"); } system("pause"); return 0; }
这里也是用了两种翻转方式实现了逆时针90度旋转,分别是上下翻转和主对角线翻转。
在主对角线的选择上也是比较有讲究的,在我原来的印象里主对角线应该是与正常x轴夹角为45度的那条。但是在矩阵代码的书写里这种习惯是不好的!!以(0,0)到(max,max)的这个斜对角先才应该是矩阵代码里的主对角线。因为从(0,0)开始书写无论是从记忆角度还是在规定时间写出更易懂易检查的代码都是更好的。
总结
相对于普遍的翻转逻辑(即用一个数组存一行的值然后一个一个去覆盖实现旋转)此旋转的优点有许多,直接通过翻转(即交换数据)来实现可以省去创造一个行列大小的临时数组去记录覆盖值,只需要三种翻折操作便可以实现上述的所有翻转操作,从代码书写难度和记忆难度来说都有很大的改善。
要旋转的矩形长宽不相等怎么办?把最大的那条边当成上述的正方形边长就可以啦。



