返回
二叉树层序遍历 II
前端
2024-02-02 14:36:42
## 二叉树层序遍历 II
在计算机科学中,二叉树是一种常见的数据结构。它由一个根节点和若干个子节点组成,每个子节点都连接到根节点。二叉树可以用于表示各种各样的数据,如文件系统、目录树、语法树等。
层序遍历是一种遍历二叉树的方法,它从根节点开始,逐层遍历二叉树的节点。层序遍历可以分为自顶向下和自底向上两种方式。自顶向下的层序遍历从根节点开始,依次遍历根节点的子节点,然后是子节点的子节点,以此类推。自底向上的层序遍历则从根节点的子节点开始,依次遍历子节点的子节点,然后是根节点的子节点,最后是根节点。
本文将介绍如何对二叉树进行层序遍历,即自底向上地遍历二叉树的节点。我们将使用两种方法来实现层序遍历:深度优先搜索(DFS)和广度优先搜索(BFS)。DFS 是一种递归方法,它从根节点开始,深度优先地遍历每个子树,直到达到叶子节点。BFS 是一种迭代方法,它使用队列来存储待访问的节点,并按照先进先出的原则遍历这些节点。我们将比较这两种方法的优缺点,并提供 Python 和 C++ 的代码实现。
### 深度优先搜索(DFS)
DFS 是一种递归方法,它从根节点开始,深度优先地遍历每个子树,直到达到叶子节点。DFS 的实现非常简单,只需对每个节点的左子树和右子树分别进行 DFS。在 Python 中,我们可以使用如下代码来实现 DFS:
```python
def dfs(root):
if root is None:
return
# 访问根节点
print(root.val)
# 递归遍历左子树
dfs(root.left)
# 递归遍历右子树
dfs(root.right)
在 C++ 中,我们可以使用如下代码来实现 DFS:
void dfs(TreeNode* root) {
if (root == nullptr) {
return;
}
// 访问根节点
std::cout << root->val << std::endl;
// 递归遍历左子树
dfs(root->left);
// 递归遍历右子树
dfs(root->right);
}
广度优先搜索(BFS)
BFS 是一种迭代方法,它使用队列来存储待访问的节点,并按照先进先出的原则遍历这些节点。BFS 的实现也非常简单,只需将根节点放入队列中,然后依次将队列中的节点取出并访问,同时将它们的子节点放入队列中。在 Python 中,我们可以使用如下代码来实现 BFS:
def bfs(root):
if root is None:
return
# 创建一个队列并加入根节点
queue = [root]
# 循环遍历队列
while queue:
# 取出队列中的第一个节点
node = queue.pop(0)
# 访问节点
print(node.val)
# 将节点的左子树和右子树加入队列
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
在 C++ 中,我们可以使用如下代码来实现 BFS:
void bfs(TreeNode* root) {
if (root == nullptr) {
return;
}
// 创建一个队列并加入根节点
std::queue<TreeNode*> queue;
queue.push(root);
// 循环遍历队列
while (!queue.empty()) {
// 取出队列中的第一个节点
TreeNode* node = queue.front();
queue.pop();
// 访问节点
std::cout << node->val << std::endl;
// 将节点的左子树和右子树加入队列
if (node->left) {
queue.push(node->left);
}
if (node->right) {
queue.push(node->right);
}
}
}
比较 DFS 和 BFS
DFS 和 BFS 都是遍历二叉树的有效方法,但它们各有优缺点。DFS 的优点是实现简单,空间复杂度低,但它在遍历深度较大的树时可能会效率较低。BFS 的优点是遍历深度较大的树时效率较高,但它的实现略微复杂一些,空间复杂度也略微高一些。
在实际应用中,我们可以根据具体情况选择使用 DFS 或 BFS。如果需要深度优先遍历二叉树,可以使用 DFS。如果需要广度优先遍历二叉树,可以使用 BFS。
Python 和 C++ 代码实现
以下是用 Python 和 C++ 实现的二叉树层序遍历 II 的代码:
# Python 代码
class TreeNode:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def dfs(root):
if root is None:
return
# 访问根节点
print(root.val)
# 递归遍历左子树
dfs(root.left)
# 递归遍历右子树
dfs(root.right)
def bfs(root):
if root is None:
return
# 创建一个队列并加入根节点
queue = [root]
# 循环遍历队列
while queue:
# 取出队列中的第一个节点
node = queue.pop(0)
# 访问节点
print(node.val)
# 将节点的左子树和右子树加入队列
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
# 创建二叉树
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.left = TreeNode(6)
root.right.right = TreeNode(7)
# 打印二叉树的层序遍历 II
print("DFS:")
dfs(root)
print("BFS:")
bfs(root)
// C++ 代码
#include <iostream>
#include <queue>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int val) : val(val), left(nullptr), right(nullptr) {}
};
void dfs(TreeNode* root) {
if (root == nullptr) {
return;
}
// 访问根节点
cout << root->val << endl;
// 递归遍历左子树
dfs(root->left);
// 递归遍历右子树
dfs(root->right);
}
void bfs(TreeNode* root) {
if (root == nullptr) {
return;
}
// 创建一个队列并加入根节点
queue<TreeNode*> queue;
queue.push(root);
// 循环遍历队列
while (!queue.empty()) {
// 取出队列中的第一个节点
TreeNode* node = queue.front();
queue.pop();
// 访问节点
cout << node->val << endl;
// 将节点的左子树和右子树加入队列
if (node->left) {
queue.push(node->left);
}
if (node->right) {
queue.push(node->right);
}
}
}
int main() {
// 创建二叉树
TreeNode* root = new TreeNode(1);
root->left = new TreeNode(2);
root->right = new TreeNode(3);
root->left->left = new TreeNode(4);
root->left->right = new TreeNode(5);
root->right->left = new TreeNode(6);
root->right->right = new TreeNode(7);