给你一颗二叉树的根节点root
,请你翻转该二叉树,并且返回其根节点。
如何判定二叉树是否翻转?
const invertTree = (root) => {
if (root == null) {
// 遍历到null节点时,不用翻转,直接返回它本身
return root;
}
invertTree(root.left);
invertTree(root.right);
const temp = root.left;
root.left = root.right;
root.right = temp;
return root;
};
const invertTree = (root) => {
if (root == null) {
// 遍历到null节点时,不用翻转,直接返回它本身
return root;
}
const temp = root.left;
root.left = root.right;
root.right = temp;
// 内部的翻转交给递归去做
invertTree(root.left);
invertTree(root.right);
return root;
};
两种分别是前序遍历和后序遍历,并且基于DFS深度优先遍历,如下实例所示:
代码,C++实现:
//排列数字,给定整数N,按照字典序排列
#include
using namespace std;
const int N = 10;
int n;
int path[N]; //用一个全局数组实现存储方法状态
bool st[N]; //判定一个数是否用过?
void dfs(int u) {
if (u == n) {
//说明一个排列已经把所有位置排满了,当前位置输出就行
for (int i = 0; i < n; i++) {
printf("%d ", path[i]);
}
puts("");
return;
}
/*u < n,说明还没有填完,也就是还没有得到一种方案数
枚举一下当前这个位置可以填哪些数 */
for (int i = 1; i <= n; i++) {
if (!st[i]) {
//找到了一个没有被用过的数
path[u] = i;
//记录该数已经被使用过
st[i] = true;
//状态处理好之后递归到下一层
dfs(u + 1);
//恢复现场,path[u] = 0没有必要,因为会被不断的覆盖
st[i] = false;
}
}
}
int main() {
cin >> n;
dfs(0);
return 0;
}
实例2,八皇后问题,给出代码如下:
//八皇后问题
#include
using namespace std;
const int N = 20;
int n;
char g[N][N]; //表示方案数
bool col[N], dg[N], udg[N]; //分别检验同一列、正反对角线是否只有一个皇后
void dfs(int u) {
if (u == n) {
//当找到一组方案的时候,输出
for (int i = 0; i < n; i++) {
puts(g[i]);
}
puts("");
return ;
}
//从前往后枚举u行,看皇后应该在哪一列
for (int i = 0; i < n; i++) {
if (!col[i] && !dg[u + i] && !udg[n - u + i]) {
//某一列,某条对角线都没有元素放入过
g[u][i] = 'Q';
//已经有皇后元素
col[i] = dg[u + i] = udg[n - u + i] = true;
dfs(u + 1);
//恢复现场
col[i] = dg[u + i] = udg[n - u + i] = false;
g[u][i] = '*';
//到这可以发现if语句完全对称
}
}
}
int main() {
cout << "请输入整数:" << endl;
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
g[i][j] = '*';
}
}
dfs(0);
return 0;
}