1、题目描述
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
返回:[3,9,20,15,7]
2、VS2019上运行
使用队列+BFS(广度优先搜索);按层遍历
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
// 层次遍历打印二叉树的节点值
vector<int> levelOrder(TreeNode* root) {
if (root == nullptr)
return {}; // 如果根节点为空,则返回空的vector
vector<int> ans; // 存储遍历结果的vector
queue<TreeNode*> q; // 辅助队列,用于层次遍历
q.push(root); // 将根节点入队
while (!q.empty()) {
auto node = q.front(); // 取队列的头节点
q.pop(); // 弹出头节点
ans.push_back(node->val); // 将节点的值加入结果vector
if (node->left)
q.push(node->left); // 如果节点有左子节点,将左子节点入队
if (node->right)
q.push(node->right); // 如果节点有右子节点,将右子节点入队
}
return ans; // 返回遍历结果
}
int main() {
// 构建二叉树
TreeNode* root = new TreeNode(3);
root->left = new TreeNode(9);
root->right = new TreeNode(20);
root->right->left = new TreeNode(15);
root->right->right = new TreeNode(7);
// 层次遍历打印二叉树的节点值
vector<int> result = levelOrder(root);
// 输出结果
cout << "Level Order Traversal: ";
for (int num : result) {
cout << num << " ";
}
cout << endl;
return 0;
}
运行结果:
Level Order Traversal: 3 9 20 15 7
3、搜索与回溯算法
- 搜索算法
1.搜索算法是一种用于系统地遍历和探索问题解空间的方法。它通常用于在大量可能的解中寻找最优解或满足特定条件的解。
2.常见的搜索算法包括深度优先搜索(DFS)、广度优先搜索(BFS)、A搜索等。
3.DFS是一种通过不断探索当前节点的所有可能路径,直到找到解或无路可走时回退到前一节点的策略。
4.BFS从图的起点开始,逐层遍历到达离起点的路径最短的节点,直到找到解或遍历完所有节点。
5.A*搜索是一种启发式搜索算法,它通过估计每个节点到目标的代价,选择下一步最有可能达到目标的节点进行搜索。 - 回溯算法
1.回溯算法是一种通过不断尝试可能的解,并在不能达到目标状态时进行回退的方法。它通常用于解决组合问题、排列问题和优化问题等。
2.回溯算法通过递归的方式进行尝试,每次选择一个可能的选项,并在尝试之后撤销选择,返回到上一级进行下一次尝试。
3.回溯算法的核心思想在于试探和回溯,通过不断地尝试和回溯来寻找问题的解。
4.典型的回溯算法问题包括八皇后问题、0-1背包问题、全排列等。 - 典型的搜索算法问题
1.迷宫问题:给定一个迷宫的布局,从起点出发,找到到达终点的路径。
2.单词搜索:给定一个字符矩阵和一个单词,判断该单词是否存在于矩阵中,可沿水平或垂直方向移动。
3.数独求解:给定一个数独游戏的初始布局,找到符合数独规则的解。
4.图的遍历:包括深度优先搜索(DFS)和广度优先搜索(BFS),用于在图中搜索路径、判断连通性等。
5.最短路径问题:例如迪杰斯特拉算法(Dijkstra’s algorithm)和贝尔曼-福特算法(Bellman-Ford algorithm),用于找到两个节点之间的最短路径。
6.拓扑排序:给定一个有向无环图,找到其中节点的一种线性排序,使得对于任意一条有向边 (u, v),节点 u 在排序中都出现在节点 v 之前。
7.八皇后问题:在8×8的棋盘上放置8个皇后,使得每个皇后不互相攻击(即任意两个皇后不在同一行、同一列或同一对角线上)。
8.深度限制搜索:对于某些问题,搜索的解空间非常大,通过设置深度限制,只搜索到一定层次,可减少搜索空间。 - 典型的回溯算法问题
1.全排列问题:给定一个数组,要求生成数组中所有元素的全排列。
2.组合求和问题:给定一个数组和一个目标数值,找出数组中所有的组合,使得它们的和等于目标数值。
3.子集问题:给定一个数组,找出数组的所有子集。
4.解数独问题:给定一个数独游戏的初始布局,填充空缺的位置,使得每一行、每一列和每一个九宫格内的数字都是1到9并且不重复。
5.N皇后问题:在N×N的棋盘上放置N个皇后,使得它们不能互相攻击(即任意两个皇后不能在同一行、同一列或同一对角线上)。
6.正则表达式匹配问题:给定一个字符串和一个正则表达式,判断字符串是否能够与正则表达式匹配。
7.字符串解码问题:给定一个编码过的字符串,根据编码规则解码该字符串。
8.图的着色问题:给定一个图,为每一个节点选择一种颜色,要求相邻节点不能有相同的颜色。
这些问题都可以使用回溯算法来解决。回溯算法的核心思想是通过不断尝试,回溯到之前的状态,继续搜索下一个可能的解,直到找到满足条件的解或者搜索完所有可能的情况。在回溯的过程中,需要进行剪枝操作,以减少不必要的搜索。
4、补充
- auto 关键字: C++11 引入的类型推断特性,它使编译器能够在编译时自动推断出变量的类型。根据右侧表达式的类型,编译器会将 node 推断为适当的类型
- 广度优先搜索与深度优先搜索的区别:
广度优先搜索(BFS)和深度优先搜索(DFS)是两种常用的图遍历算法,也可以用于树的遍历。它们之间的主要区别在于遍历顺序和使用的数据结构。
1.遍历顺序:
广度优先搜索(BFS)按层遍历,从起始节点开始逐层扩展,先处理同一层的所有节点,然后再处理下一层的节点。
深度优先搜索(DFS)沿着路径进行遍历,尽可能深入树或图的每个分支,并在到达叶子节点或无法继续前进时回溯到上一级。
2.数据结构:
广度优先搜索(BFS)通常使用队列(Queue)作为辅助数据结构,通过先进先出(FIFO)的原则处理节点。
深度优先搜索(DFS)通常使用递归或栈(Stack)作为辅助数据结构,在递归过程中对节点进行操作或将节点压入栈中。
3.搜索性质:
广度优先搜索(BFS)能够找到最短路径,即从起始节点到目标节点的最少步骤。
深度优先搜索(DFS)能够找到路径中的一条,但不一定是最短路径。
4.选择使用广度优先搜索还是深度优先搜索取决于具体问题的需求和特点:
如果需要寻找最短路径或找到离起点最近的节点,广度优先搜索是更好的选择。
如果问题需要遍历尽可能深的节点,或者需要得到所有可能的路径或组合,深度优先搜索更适合。