📚 一、什么是二维数组?
想象你有一张表格,就像九宫格:
原始数组(3×3)
┌─────┬─────┬─────┐
│ 1 │ 2 │ 3 │
├─────┼─────┼─────┤
│ 4 │ 5 │ 6 │
├─────┼─────┼─────┤
│ 7 │ 8 │ 9 │
└─────┴─────┴─────┘
🔄 二、数组转置(行列交换)
什么是转置?
把行变成列,把列变成行,就像把表格斜着转一下!
转置前 转置后
┌─────┬─────┬─────┐ ┌─────┬─────┬─────┐
│ 1 │ 2 │ 3 │ │ 1 │ 4 │ 7 │
├─────┼─────┼─────┤ → ├─────┼─────┼─────┤
│ 4 │ 5 │ 6 │ │ 2 │ 5 │ 8 │
├─────┼─────┼─────┤ ├─────┼─────┼─────┤
│ 7 │ 8 │ 9 │ │ 3 │ 6 │ 9 │
└─────┴─────┴─────┘ └─────┴─────┴─────┘
变化:m[i][j] → m[j][i]
代码实现:
#include <iostream>
using namespace std;
int main() {
// 定义原始数组
int m[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 输出原始数组
cout << "原始数组:\n";
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << m[i][j] << " ";
}
cout << endl;
}
// 转置:交换行和列
int temp[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
temp[j][i] = m[i][j]; // 关键:行列交换
}
}
// 输出转置后的数组
cout << "\n转置后的数组:\n";
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << temp[i][j] << " ";
}
cout << endl;
}
return 0;
}
结果:
原始数组:
1 2 3
4 5 6
7 8 9
转置后的数组:
1 4 7
2 5 8
3 6 9
🔃 三、数组旋转(顺时针90度)
什么是旋转?
把整个数组向右转90度,就像把图片顺时针旋转!
旋转前 旋转后(顺时针90度)
┌─────┬─────┬─────┐ ┌─────┬─────┬─────┐
│ 1 │ 2 │ 3 │ │ 7 │ 4 │ 1 │
├─────┼─────┼─────┤ → ├─────┼─────┼─────┤
│ 4 │ 5 │ 6 │ │ 8 │ 5 │ 2 │
├─────┼─────┼─────┤ ├─────┼─────┼─────┤
│ 7 │ 8 │ 9 │ │ 9 │ 6 │ 3 │
└─────┴─────┴─────┘ └─────┴─────┴─────┘
变化规律:
- 第1列变成第1行(倒序):7, 4, 1
- 第2列变成第2行(倒序):8, 5, 2
- 第3列变成第3行(倒序):9, 6, 3
代码实现
#include <iostream>
using namespace std;
int main() {
// 定义原始数组
int m[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 输出原始数组
cout << "原始数组:\n";
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << m[i][j] << " ";
}
cout << endl;
}
// 旋转90度(顺时针)
int temp[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
temp[i][j] = m[3-1-j][i]; // 关键公式
}
}
// 输出旋转后的数组
cout << "\n旋转后的数组(顺时针90度):\n";
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << temp[i][j] << " ";
}
cout << endl;
}
return 0;
}
结果:
原始数组:
1 2 3
4 5 6
7 8 9
旋转后的数组(顺时针90度):
7 4 1
8 5 2
9 6 3
旋转规律总结
旋转前的位置 [i][j] → 旋转后的位置 [j][n-1-i]
其中 n 是数组的行数(或列数)
例如:
m[0][0] (值为1) → temp[0][2]
m[0][1] (值为2) → temp[1][2]
m[0][2] (值为3) → temp[2][2]
m[1][0] (值为4) → temp[0][1]
...
📜 四、数组行滚动(向上滚动)
什么是向上滚动?
把第一行移到最后一行,其他行都向上移动一行!
滚动前 滚动后(向上滚动1次)
┌─────┬─────┬─────┐ ┌─────┬─────┬─────┐
│ 1 │ 2 │ 3 │ │ 4 │ 5 │ 6 │ ← 第2行变成第1行
├─────┼─────┼─────┤ → ├─────┼─────┼─────┤
│ 4 │ 5 │ 6 │ │ 7 │ 8 │ 9 │ ← 第3行变成第2行
├─────┼─────┼─────┤ ├─────┼─────┼─────┤
│ 7 │ 8 │ 9 │ │ 1 │ 2 │ 3 │ ← 第1行变成第3行
└─────┴─────┴─────┘ └─────┴─────┴─────┘
代码实现:
#include <iostream>
using namespace std;
int main() {
// 定义原始数组
int m[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 输出原始数组
cout << "原始数组:\n";
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << m[i][j] << " ";
}
cout << endl;
}
// 保存第0行(要移到最后一行)
int temp[3];
for (int j = 0; j < 3; j++) {
temp[j] = m[0][j];
}
// 向上滚动:第1行变成第0行,第2行变成第1行
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
m[i][j] = m[i+1][j];
}
}
// 把原来的第0行放到最后一行
for (int j = 0; j < 3; j++) {
m[2][j] = temp[j];
}
// 输出滚动后的数组
cout << "\n向上滚动1次后的数组:\n";
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << m[i][j] << " ";
}
cout << endl;
}
return 0;
}
结果:
原始数组:
1 2 3
4 5 6
7 8 9
向上滚动1次后的数组:
4 5 6
7 8 9
1 2 3
更简单的方法(直接交换)
#include <iostream>
using namespace std;
int main() {
int m[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
cout << "原始数组:\n";
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << m[i][j] << " ";
}
cout << endl;
}
// 交换第0行和第1行
for (int j = 0; j < 3; j++) {
int t = m[0][j];
m[0][j] = m[1][j];
m[1][j] = m[2][j];
m[2][j] = t;
}
cout << "\n向上滚动1次后的数组:\n";
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << m[i][j] << " ";
}
cout << endl;
}
return 0;
}
📜 五、数组行滚动(向下滚动)
什么是向下滚动?
把最后一行移到第一行,其他行都向下移动一行!
滚动前 滚动后(向下滚动1次)
┌─────┬─────┬─────┐ ┌─────┬─────┬─────┐
│ 1 │ 2 │ 3 │ │ 7 │ 8 │ 9 │ ← 第3行变成第1行
├─────┼─────┼─────┤ → ├─────┼─────┼─────┤
│ 4 │ 5 │ 6 │ │ 1 │ 2 │ 3 │ ← 第1行变成第2行
├─────┼─────┼─────┤ ├─────┼─────┼─────┤
│ 7 │ 8 │ 9 │ │ 4 │ 5 │ 6 │ ← 第2行变成第3行
└─────┴─────┴─────┘ └─────┴─────┴─────┘
代码实现:
#include <iostream>
using namespace std;
int main() {
// 定义原始数组
int m[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 输出原始数组
cout << "原始数组:\n";
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << m[i][j] << " ";
}
cout << endl;
}
// 保存最后一行(要移到第一行)
int temp[3];
for (int j = 0; j < 3; j++) {
temp[j] = m[2][j];
}
// 向下滚动:第2行变成第3行,第1行变成第2行
for (int i = 2; i > 0; i--) {
for (int j = 0; j < 3; j++) {
m[i][j] = m[i-1][j];
}
}
// 把原来的最后一行放到第一行
for (int j = 0; j < 3; j++) {
m[0][j] = temp[j];
}
// 输出滚动后的数组
cout << "\n向下滚动1次后的数组:\n";
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << m[i][j] << " ";
}
cout << endl;
}
return 0;
}
结果:
原始数组:
1 2 3
4 5 6
7 8 9
向下滚动1次后的数组:
7 8 9
1 2 3
4 5 6
💡 七、小技巧
1. 使用模运算简化滚动
// 向上滚动:新位置 = (i + 1) % n
// 向下滚动:新位置 = (i + n - 1) % n 或 (i + 2) % n(当n=3时)
2. 记住转置公式
// 转置:m[i][j] → m[j][i]
temp[j][i] = m[i][j];
3. 记住旋转公式
// 旋转90度:m[i][j] → m[j][n-1-i]
temp[j][n-1-i] = m[i][j];
📝 总结
| 操作 | 变化规律 | 记忆方法 |
|---|---|---|
| 转置 | m[i][j] → m[j][i] | 行列交换,像照镜子 |
| 旋转90度 | m[i][j] → m[j][n-1-i] | 先转置再倒序 |
| 向上滚动 | 第1行移到最后一行 | 像电梯向上 |
| 向下滚动 | 最后1行移到第1行 | 像电梯向下 |
关键公式
- 转置公式:
temp[j][i] = m[i][j] - 旋转公式:
temp[i][j] = m[n-1-j][i] - 向上滚动:
m[(i+1)%n][j] - 向下滚动:
m[(i+n-1)%n][j]
🎨 八、练习题
练习1:转置4×4数组
int m[4][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
};
// 请写出转置后的数组
练习2:旋转4×4数组90度
// 原始数组同上
// 请写出旋转90度后的数组
练习3:连续向上滚动2次
int m[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 连续向上滚动2次,数组变成什么?
7 8 9
1 2 3
4 5 6


875

被折叠的 条评论
为什么被折叠?



