909-2015-T3

news2024/7/4 4:46:20

文章目录

  • 1.原题
  • 2.算法思想
    • 2.1.求树的高度
    • 2.2.求路径
  • 3.关键代码
  • 4.完整代码
  • 5.输出结果

1.原题

试编写算法,求给定二叉树上从根节点到叶子节点的一条路径长度等于树的深度减一的路径(即列出从根节点到该叶子节点的节点序列),若这样的路径存在多条,则输出路径终点在“最左”的一条。

2.算法思想

计算出树的高度,然后再进行类前序遍历,输出路径为最深的、最靠左的一条。分为两部分。1.求树的高度;2.求路径

2.1.求树的高度

这个算法在14年某个题已经涉及到了。通过遍历的方式得出每一个结点的左子树高度和右子树高度,而该结点的高度就是左子树高度和右子树高度较大的那一个+1

2.2.求路径

由于是求最靠左的一条、最深的一条路径,那么用类先序遍历的方式进行探索最有优势。根据先序遍历的特点,我们第一次找到的路径即为最左边的。同时引入了一个变量isFound,这样在找到一条路径之后可以更快跳过后续的递归嵌套。

3.关键代码

/**
 * @struct treeNode
 * @brief 二叉树节点的结构体
 */
struct treeNode {
    int data; /**< 节点存储的数据 */
    struct treeNode *lchild; /**< 左子节点指针 */
    struct treeNode *rchild; /**< 右子节点指针 */
};

/**
 * @brief 计算二叉树的高度。
 *
 * 通过递归地计算左右子树的高度,返回树的高度。
 *
 * @param root 二叉树根节点指针。
 * @return 返回二叉树的高度。
 */
int treeHeight(struct treeNode *root) {
    if (root == NULL) {
        return 0; // 如果根节点为空,返回0表示树的高度为0
    } else {
        int leftHeight = treeHeight(root->lchild); // 递归计算左子树的高度
        int rightHeight = treeHeight(root->rchild); // 递归计算右子树的高度

        // 返回左右子树中较大的高度加上当前节点的高度(加1)
        return (leftHeight > rightHeight) ? leftHeight + 1 : rightHeight + 1;
    }
}

/**
 * @brief 在二叉树中查找具有特定深度的路径
 *
 * 通过递归遍历二叉树,查找根到叶子节点的路径,其深度等于指定高度,并打印该路径。
 *
 * @param root 二叉树根节点指针。
 * @param isFound 指向一个布尔值的指针,用于判断是否已找到特定深度的路径。
 * @param height 期望的路径深度。
 * @param depth 当前递归深度。
 * @param path 用于存储路径节点值的数组。
 */
void findPath(struct treeNode *root, bool *isFound, int height, int depth, int path[]) {
    if (root == NULL || (*isFound) == true) {
        return; // 如果根节点为空或已找到路径,则直接返回
    }

    path[depth] = root->data; // 将当前节点值存入路径数组中

    if (depth == height - 1) {
        (*isFound) = true; // 标记已找到路径
        for (int i = 0; i < height; i++) {
            printf("%d ", path[i]); // 打印路径节点值
        }
        printf("\n");
        return;
    } else {
        depth += 1; // 增加深度
        findPath(root->lchild, isFound, height, depth, path); // 递归遍历左子树
        findPath(root->rchild, isFound, height, depth, path); // 递归遍历右子树
    }
}

/**
 * @brief 寻找二叉树中指定深度的路径
 *
 * 通过计算二叉树的高度,创建对应高度的数组,并在树中查找深度为高度减一的路径。
 * 找到后打印该路径上的节点值。
 *
 * @param root 二叉树根节点指针。
 */
void findSpecialPath(struct treeNode *root) {
    int height = treeHeight(root); // 计算二叉树的高度
    int path[height]; // 创建与高度相同大小的数组,用于存储路径节点值
    bool isFound = false; // 指示是否找到特定深度的路径

    findPath(root, &isFound, height, 0, path); // 查找特定深度的路径
}

4.完整代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

/**
 * @struct treeNode
 * @brief 二叉树节点的结构体
 */
struct treeNode {
    int data; /**< 节点存储的数据 */
    struct treeNode *lchild; /**< 左子节点指针 */
    struct treeNode *rchild; /**< 右子节点指针 */
};

/**
 * @brief 计算二叉树的高度。
 *
 * 通过递归地计算左右子树的高度,返回树的高度。
 *
 * @param root 二叉树根节点指针。
 * @return 返回二叉树的高度。
 */
int treeHeight(struct treeNode *root) {
    if (root == NULL) {
        return 0; // 如果根节点为空,返回0表示树的高度为0
    } else {
        int leftHeight = treeHeight(root->lchild); // 递归计算左子树的高度
        int rightHeight = treeHeight(root->rchild); // 递归计算右子树的高度

        // 返回左右子树中较大的高度加上当前节点的高度(加1)
        return (leftHeight > rightHeight) ? leftHeight + 1 : rightHeight + 1;
    }
}

/**
 * @brief 在二叉树中查找具有特定深度的路径
 *
 * 通过递归遍历二叉树,查找根到叶子节点的路径,其深度等于指定高度,并打印该路径。
 *
 * @param root 二叉树根节点指针。
 * @param isFound 指向一个布尔值的指针,用于判断是否已找到特定深度的路径。
 * @param height 期望的路径深度。
 * @param depth 当前递归深度。
 * @param path 用于存储路径节点值的数组。
 */
void findPath(struct treeNode *root, bool *isFound, int height, int depth, int path[]) {
    if (root == NULL || (*isFound) == true) {
        return; // 如果根节点为空或已找到路径,则直接返回
    }

    path[depth] = root->data; // 将当前节点值存入路径数组中

    if (depth == height - 1) {
        (*isFound) = true; // 标记已找到路径
        for (int i = 0; i < height; i++) {
            printf("%d ", path[i]); // 打印路径节点值
        }
        printf("\n");
        return;
    } else {
        depth += 1; // 增加深度
        findPath(root->lchild, isFound, height, depth, path); // 递归遍历左子树
        findPath(root->rchild, isFound, height, depth, path); // 递归遍历右子树
    }
}

/**
 * @brief 寻找二叉树中指定深度的路径
 *
 * 通过计算二叉树的高度,创建对应高度的数组,并在树中查找深度为高度减一的路径。
 * 找到后打印该路径上的节点值。
 *
 * @param root 二叉树根节点指针。
 */
void findSpecialPath(struct treeNode *root) {
    int height = treeHeight(root); // 计算二叉树的高度
    int path[height]; // 创建与高度相同大小的数组,用于存储路径节点值
    bool isFound = false; // 指示是否找到特定深度的路径

    findPath(root, &isFound, height, 0, path); // 查找特定深度的路径
}

/**
 * @brief 创建新的二叉树节点。
 *
 * @param data 新节点存储的数据。
 * @return 指向新节点的指针。
 */
struct treeNode *createNode(int data) {
    struct treeNode *newNode = (struct treeNode *) malloc(sizeof(struct treeNode));
    newNode->data = data;
    newNode->lchild = NULL;
    newNode->rchild = NULL;
    return newNode;
}

/**
 * @brief 以括号表示法打印二叉树。
 *
 * @param root 二叉树根节点指针。
 */
void printBinaryTree(struct treeNode *root) {
    if (root == NULL) {
        return;
    }
    printf("(%d", root->data);
    if (root->lchild != NULL || root->rchild != NULL) {
        printf(" ");
        if (root->lchild == NULL) {
            printf("( )");
        } else {
            printBinaryTree(root->lchild);
        }
        printf(" ");
        if (root->rchild == NULL) {
            printf("( )");
        } else {
            printBinaryTree(root->rchild);
        }
    }
    printf(")");
}

/**
 * @brief 以树的结构方式打印二叉树。
 *
 * @param root 二叉树根节点指针。
 * @param space 节点之间的间距。
 */
void printTreeStructure(struct treeNode *root, int space) {
    if (root == NULL) {
        return;
    }

    int count = 5; // 调整节点之间的间距

    printTreeStructure(root->rchild, space + count);

    for (int i = 0; i < space; i++) {
        printf(" ");
    }
    printf("%d\n", root->data);

    printTreeStructure(root->lchild, space + count);
}


int main() {
    struct treeNode *root = createNode(10);  // 根节点为10
    root->lchild = createNode(5);
    root->rchild = createNode(15);
    root->lchild->lchild = createNode(3);
    root->rchild->lchild = createNode(12);
    root->rchild->rchild = createNode(18);
    root->rchild->lchild->rchild = createNode(13);
    root->rchild->rchild->rchild = createNode(9);


    // 以括号表示法打印二叉树
    printf("Binary Tree Structure (Parenthesis Representation):\n");
    printBinaryTree(root);

    // 以树的结构方式打印二叉树
    printf("\nBinary Tree Structure:\n");
    printTreeStructure(root, 0);

    int height = treeHeight(root);
    printf("Height of the tree: %d\n", height);

    // 寻找特定路径并打印
    printf("Special Path with length equal to tree depth - 1: \n");
    findSpecialPath(root);

    return 0;
}

5.输出结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1238936.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaEE】Spring更简单的存储和获取对象(类注解、方法注解、属性注入、Setter注入、构造方法注入)

一、存储Bean对象 在这篇文章中我介绍了Spring最简单的创建和使用&#xff1a;Spring的创建和使用 其中存储Bean对象是这样的&#xff1a; 1.1 配置扫描路径 想要成功把对象存到Spring中&#xff0c;我们需要配置对象的扫描包路径 这样的话&#xff0c;就只有被配置了的包…

STM32F103C8T6第5天:独立看门狗、窗口看门狗、dma实验

1. 独立看门狗IWDG介绍&#xff08;341.45&#xff09; 什么是看门狗&#xff1f; 在由单片机构成的微型计算机系统中&#xff0c;由于单片机的工作常常会受到来自外界电磁场的干扰&#xff0c;造成程序的跑飞&#xff0c;而陷入死循环&#xff0c;程序的正常运行被打断&#…

引爆关注,聚焦上海新闻媒体邀请

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 上海拥有众多的新闻媒体机构&#xff0c;包括报纸、电视、广播和网络媒体等。这些媒体在报道国内外新闻、传播信息等方面发挥着重要作用。 其中&#xff0c;上海电视台是上海最大的电视…

使用VSCode+PlatformIO搭建ESP32开发环境

Arduino IDE本来就是为创客们开发的&#xff0c;虽然没代码提示功能&#xff0c;文件的关系也不清晰&#xff0c;函数不能跳转&#xff0c;头文件也打不开&#xff0c;但人家的初衷就是为了简单而生的&#xff1b;但还是有一些同学喜欢高级点的IDE&#xff0c;也没问题&#xf…

详解Python中哈希表的使用。站在开发者角度,与大家一起探究哈希的世界。

文章目录 1. 前言2. 哈希表2.1 哈希函数2.2 哈希算法2.3 常见哈希算法2.4 哈希冲突 3.总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面…

算法设计与分析复习--分支界限法

文章目录 上一篇分支界限法性质装载问题0-1背包问题单源最短路问题最大团问题下一篇 上一篇 算法设计与分析复习–回溯法&#xff08;二&#xff09; 分支界限法性质 分支界限法是按广度优先策略或最小耗费优先遍历问题的解空间树。 搜索解空间&#xff1a; 子集树排列树 …

2024贵州大学计算机考研分析

24计算机考研|上岸指南 贵州大学 贵州大学计算机科学与技术学院&#xff08;贵州大学省级示范性软件学院&#xff09;位于贵州省贵阳市花溪区贵州大学东校区。 计算机科学与技术学院&#xff08;软件学院&#xff09;自1972年创办计算机软件本科专业开始&#xff0c;至今已有…

sso 四种授权模式

单点登录 单点登录&#xff0c;英文是 Single Sign On&#xff08;缩写为 SSO&#xff09;。即多个站点共用一台认证授权服务器&#xff0c;用户在站点登录后&#xff0c;可以免登录访问其他所有站点。而且&#xff0c;各站点间可以通过该登录状态直接交互。例如&#xff1a; …

aspera替代方案,镭速大文件传输解决方案替代

相信不少的互联网用户对于传输软件aspera并不陌生&#xff0c;但是市面上有没有哪一些aspera替代方案&#xff0c;aspera替代方案是否比aspera更加能够解决数据传输的需求&#xff0c;是一个值得思考的事情&#xff0c;那么我们先来了解一下aspera以及aspera替代方案。 了解Asp…

[Linux] shell条件语句和if语句

一、条件语句 1.1 测试 test 测试文件的表达式是否成立 格式&#xff1a;test 条件表达式 [ 条件表达式 ] 选项作用-d测试是否为目录-e测试目录或文件是否存在-a测试目录或文件是否存在-f测试是否为文件-r测试当前用户是否有权限读取-w测试当前用户是否有权限写入-x测试当前…

csdn最新最全pytest系列——pluggy插件源码解读(一)HookspecMarker类和HookimplMarker类分析

简介 pluggy是一个非常优秀的插件系统&#xff0c;它是理解pytest的核心&#xff0c;只有理解了pluggy的原理&#xff0c;才能更好的理解和使用pytest&#xff0c;否则见到了pytest的很多应用都会感觉很难理解 pluggy插件总共的代码量不足一千行&#xff0c;而实现的功能却是…

SpringBoot : ch06 整合 web (一)

前言 SpringBoot作为一款优秀的框架&#xff0c;不仅提供了快速开发的能力&#xff0c;同时也提供了丰富的文档和示例&#xff0c;让开发者更加容易上手。在本博客中&#xff0c;我们将介绍如何使用SpringBoot来整合Web应用程序的相关技术&#xff0c;并通过实例代码来演示如何…

Axios简单使用与配置安装-Vue

安装Axios npm i axios main.js 导入 import Axios from axios Vue.prototype.$axios Axios简单发送请求 get getTest() {this.$axios({method: GET,url: https://apis.jxcxin.cn/api/title?urlhttps://apis.jxcxin.cn/}).then(res > {//请求成功回调console.log(res)}…

使用ChatGPT创建Makefile构建系统:使用Make运行Docker

使用ChatGPT创建Makefile构建系统&#xff1a;使用Make运行Docker 芯语芯愿&#xff08;知乎/纷传/CSDN/&#xff09;&#xff1b;小石头的芯语芯愿&#xff08;微信公众号&#xff09; 开发高效现代的构建系统对于满足开发周期需求至关重要。原先&#xff0c;嵌入式开发者一…

多选按钮关联多个el-checkbox-group

需求&#xff1a; 如图设计稿&#xff0c;全部企业成员下面的数据来源与两个接口&#xff0c;点击全部企业成员需要勾选全部&#xff0c;下面选中全部企业成员要是选中状态&#xff0c;所以需要两个数组变量&#xff0c;两个el-checkbox-group来控制&#xff1b;有人可能会疑问…

Git远程库操作(GitHub)

GitHub 网址&#xff1a;https://github.com/ 创建远程仓库 远程仓库操作 命令名称作用git remote -v查看当前所有远程地址别名git remote add 别名 远程地址起别名git push 别名 分支推送本地分支上的内容到远程仓库git clone 远程地址将远程仓库的内容克隆到本地git pull 别…

OSG文字-HUD显示汉字示例(3)

显示文字是一种非常实用的技术&#xff0c;可以用来把一些重要的文字始终显示在屏幕上。HUD的全称是HeadsUpDisplay&#xff0c;即抬头显示&#xff0c;这种技术最早应用在军事战斗机上。 创建HUD显示的基本步骤如下: <1> 创建一个osg::Camera对象&#xff0c;设置视图、…

利用QRCode.js生成动态二维码页面

文章目录 QRCode.js简介HTML结构JavaScript生成动态二维码拓展功能1. 联系信息二维码2. Wi-Fi网络信息二维码 总结 &#x1f389;利用QRCode.js生成动态二维码页面 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章专栏…

接口自动化测试实战经验分享,测试用例也能自动生成

作为测试&#xff0c;你可能会对以下场景感到似曾相识&#xff1a;开发改好的 BUG 反复横跳&#xff1b;版本兼容逻辑多&#xff0c;修复一个 BUG 触发了更多 BUG&#xff1b;上线时系统监控毫无异常&#xff0c;过段时间用户投诉某个页面无数据&#xff1b;改动祖传代码时如履…

OSG文字-osgText3D(5)

osgText3D 三维立体文字比二维平面文字显示效果更好&#xff0c;相对二维平面文字&#xff0c;它有非常好的立体显示效果。 在实际虚拟现实项目中&#xff0c;过多使用三维立体文字会降低染效率&#xff0c;加重渲染负担&#xff0c;相对平面二维文字&#xff0c;它占用的内存是…