【4.6】图搜索算法-DFS和BFS解合并二叉树

news/2024/9/28 1:17:18 标签: 图搜索算法, 深度优先, 宽度优先, c++, 算法

一、题目

        给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。你需要将他们合并为一个新的二叉树。合并的规则是 如果两个节点重叠,那么将他们的 值相加作为节点合并后的新值,否则不为 NUL L 的节点将直接作为新二叉树的节点

示例 1:

合并后的树如下

注意 : 合并必须从两个树的根节点开始。

二、解题思路

DFS思路:

合并两棵二叉树时,可能会遇到以下三种情况:

1. 两个节点都为空:在这种情况下,不需要进行合并操作。
2. 一个节点为空,另一个节点不为空:合并的结果将是不为空的那个节点。
3. 两个节点都不为空:合并后的节点值将是这两个节点值的和。

我们一起画图看看

BFS思路:

除了 DFS 我们还可以使用 BFS ,就是一层一层的遍历,合并的原理和上面一样

这里描述的是将第二棵树合并到第一棵树上的过程:

- 如果第一棵树的左子节点为空,直接将第二棵树的左子节点赋值给第一棵树的左子节点。
- 如果第一棵树的左子节点不为空,而第二棵树的左子节点为空,直接返回第一棵树的左子节点。
- 如果第一棵树的左子节点和第二棵树的左子节点都不为空,直接将它们的值相加。

右子树和上面原理一样。

三、代码实现

DFS代码:

#include <iostream>

using namespace std;

// 定义二叉树节点结构
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
    // 如果两个节点都为空,直接返回空
    if (t1 == nullptr && t2 == nullptr)
        return nullptr;
    // 如果t1节点为空,就返回t2节点
    if (t1 == nullptr)
        return t2;
    // 如果t2节点为空,就返回t1节点
    if (t2 == nullptr)
        return t1;
    // 走到这一步,说明两个节点都不为空,然后需要把这两个节点
    // 合并成一个新的节点
    TreeNode* newNode = new TreeNode(t1->val + t2->val);
    // 当前节点t1和t2合并完之后,还要继续合并t1和t2的子节点
    newNode->left = mergeTrees(t1->left, t2->left);
    newNode->right = mergeTrees(t1->right, t2->right);
    return newNode;
}

// 辅助函数:前序遍历打印二叉树
void preOrderPrint(TreeNode* root) {
    if (root == nullptr)
        return;
    cout << root->val << " ";
    preOrderPrint(root->left);
    preOrderPrint(root->right);
}

int main() {
    // 示例二叉树1
    TreeNode* t1 = new TreeNode(1);
    t1->left = new TreeNode(3);
    t1->right = new TreeNode(2);
    t1->left->left = new TreeNode(5);

    // 示例二叉树2
    TreeNode* t2 = new TreeNode(2);
    t2->left = new TreeNode(1);
    t2->right = new TreeNode(3);
    t2->left->right = new TreeNode(4);
    t2->right->right = new TreeNode(7);

    // 合并两棵二叉树
    TreeNode* mergedTree = mergeTrees(t1, t2);

    // 打印合并后的二叉树
    cout << "合并后的二叉树前序遍历结果: ";
    preOrderPrint(mergedTree);
    cout << endl;

    return 0;
}

BFS代码:

#include <iostream>
#include <queue>

using namespace std;

// 定义二叉树节点结构
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

// 把第2棵树合并到第1棵树上
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
    // 如果t1节点为空,就返回t2节点
    if (t1 == nullptr)
        return t2;
    // 如果t2节点为空,就返回t1节点
    if (t2 == nullptr)
        return t1;

    // 队列中两棵树的节点同时存在
    queue<TreeNode*> q;
    // 把这两棵树的节点同时入队
    q.push(t1);
    q.push(t2);

    while (!q.empty()) {
        // 两棵树的节点同时出队
        TreeNode* node1 = q.front();
        q.pop();
        TreeNode* node2 = q.front();
        q.pop();

        // 把这两个节点的值相加,然后合并到第1棵树的节点上
        node1->val += node2->val;

        if (node1->left == nullptr) {
            // 如果node1左子节点为空,我们直接让node2的
            // 左子结点成为node1的左子结点,
            node1->left = node2->left;
        } else {
            // 执行到这一步,说明node1的左子节点不为空,
            // 如果node2的左子节点为空就不需要合并了,
            // 只有node2的左子节点不为空的时候才需要合并
            if (node2->left != nullptr) {
                q.push(node1->left);
                q.push(node2->left);
            }
        }

        // 原理同上,上面判断的是左子节点,这里判断的是右子节点
        if (node1->right == nullptr) {
            node1->right = node2->right;
        } else {
            if (node2->right != nullptr) {
                q.push(node1->right);
                q.push(node2->right);
            }
        }
    }

    // 把第2棵树合并到第1棵树上,所以返回的是第1棵树
    return t1;
}

// 辅助函数:前序遍历打印二叉树
void preOrderPrint(TreeNode* root) {
    if (root == nullptr)
        return;
    cout << root->val << " ";
    preOrderPrint(root->left);
    preOrderPrint(root->right);
}

int main() {
    // 示例二叉树1
    TreeNode* t1 = new TreeNode(1);
    t1->left = new TreeNode(3);
    t1->right = new TreeNode(2);
    t1->left->left = new TreeNode(5);

    // 示例二叉树2
    TreeNode* t2 = new TreeNode(2);
    t2->left = new TreeNode(1);
    t2->right = new TreeNode(3);
    t2->left->right = new TreeNode(4);
    t2->right->right = new TreeNode(7);

    // 合并两棵二叉树
    TreeNode* mergedTree = mergeTrees(t1, t2);

    // 打印合并后的二叉树
    cout << "合并后的二叉树前序遍历结果: ";
    preOrderPrint(mergedTree);
    cout << endl;

    return 0;
}


http://www.niftyadmin.cn/n/5680015.html

相关文章

浅谈抗量子密码学:保护未来的数字安全

一、引言 随着量子计算机技术的发展&#xff0c;传统的加密算法面临前所未有的挑战。量子计算机利用量子位&#xff08;qubits&#xff09;的特性&#xff0c;能够在理论上比经典计算机更快地破解现有的加密系统。为了应对这一威胁&#xff0c;研究者们正在开发所谓的“抗量子…

Docker全家桶:Docker Compose项目部署

在学习完了前面的基础知识之后&#xff0c;我们现在可以开始部署完整的项目了。项目分成两个部分&#xff0c;前端和后端&#xff0c;并且采用前后端分离的形式。对应到docker&#xff0c;就是前端和后端分别对应一个容器。把这两个容器加入到同一个网段中&#xff0c;就能够进…

栈的各种接口的实现(C)

栈的概念 栈&#xff1a; 一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。压栈&#xff1a;…

RuoYi若依框架学习:多环境配置

在开发过程中&#xff0c;项目往往需要在不同的环境&#xff08;如开发、测试和生产&#xff09;中运行。RuoYi框架支持通过配置文件轻松实现多环境管理。以下是如何配置和使用多环境的技术分析。 1. 环境配置文件 RuoYi框架使用application-{profile}.yml文件来管理不同环境…

双十一购物节:五大必买爆款科技好物,让你省钱又省心

双十一购物节&#xff0c;作为中国最大的在线购物狂欢节&#xff0c;每年都吸引着无数消费者的眼球。在这个购物盛宴中&#xff0c;科技产品因其创新性、实用性和高性价比而成为消费者关注的焦点。随着科技的飞速发展&#xff0c;越来越多的智能设备走进了我们的生活&#xff0…

Vue2项目中vuex如何简化程序代码,提升代码质量和开发效率

Vuex为Vue中提供了集中式存储 库&#xff0c;其主要分为state、getter、mutation、action四个模块&#xff0c;它们每个担任了不同角色&#xff0c;分工不同&#xff1b;Vuex允许所有的组件共享状态抽取出来&#xff0c;以一个全局单例模式管理&#xff0c;状态集中存储在同一…

基于Hive和Hadoop的电商消费分析系统

本项目是一个基于大数据技术的电商消费分析系统&#xff0c;旨在为用户提供全面的电商消费信息和深入的消费行为分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xff0c;以 S…

C++系列-STL容器中算法中的最大最小

STL容器中算法中的最大最小 最大最小相关算法最大最小相关示例 最大最小相关算法 算法名称描述max(a, b)返回两个元素中较大的一个&#xff0c;return _Left < _Right ? _Right : _Left;max(a, b, pred)使用谓词作大小比较&#xff0c;return _Pred(_Left, _Right) ? _Ri…