刷题日记——重建二叉树专题

1.层序建树

给定一个二叉树的层序遍历序列,空节点用#表示,例如层序序列:“abc##de#g##f###”,其对应二叉树如下图所示:

在这里插入图片描述

分析

  1. 创建根节点 TreeNode * root=NULL
  2. 创建一个队列,用于保存将要插入的位置(先进先出)
  3. 读取字符:
    • 如果不是#,表明是非空结点,创建一个TreeNode对象,把该对象的左右孩子入队;然后判断root是否空
      • 若空,直接插入,让root指向新的TreeNode对象
      • 非空,访问队列找到本次插入的位置,插入
    • 若是#,访问队列,找到本次插入的位置,置为空指针,然后出队

代码:

#include <cstdio>
#include <queue>
#include <cmath>
#include <cstring>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;struct treenode {char data;treenode *left;treenode *right;
};struct queuenode {treenode *parent;bool isleftin;
};//从队列中取出父节点信息并将当前结点信息插入
void construct(treenode *newnode, queue<queuenode *> &myq) {queuenode *parent = myq.front();if (parent->isleftin == false) { //左孩子尚未操作parent->parent->left = newnode;parent->isleftin = true;} else {parent->parent->right = newnode;myq.pop();delete parent;//出队后queuenode结点没有利用价值了}
}void insert(treenode *&root, queue<queuenode *> &myq, char data) {if (data != '#') {treenode *newnode = new treenode;newnode->data = data;queuenode *que_member = new queuenode;que_member->parent = newnode;que_member->isleftin = false;myq.push(que_member);if (root == NULL) {root = newnode;} else {construct(newnode, myq);}} else {//是#,插入空节点if (root != NULL) {treenode *newnode = NULL;construct(newnode, myq);}}
}void levelorder(treenode *root) {queue<treenode *> myq;myq.push(root);while (myq.empty() != true) {treenode *temp = myq.front();if (temp->left != NULL) {myq.push(temp->left);}if (temp->right != NULL) {myq.push(temp->right);}myq.pop();printf("%c", temp->data);}
}void preorder(treenode *root) {if (root == NULL) {return;}printf("%c", root->data);preorder(root->left);preorder(root->right);
}int main() {char list[] = "abc##de#g##f###";treenode *root = NULL;queue<queuenode *> myq;for (int i = 0; i < strlen(list); i++) {insert(root, myq, list[i]);}preorder(root);printf("\n");levelorder(root);return 0;
}

2.先序建树

给定一个二叉树的先序遍历序列,空节点用#表示,例如先序序列:“ab##cd#gf###e##”,其对应二叉树如下图所示:
在这里插入图片描述

分析

使用递归的思想:

  1. 大事化小:
    • 读取第一个非#字符:树的根
    • 接下来的非#字符:左子树根
    • 再接下来的非#字符:右子树根
  2. 最小问题:读取到#,表明是空树,需要往回走了

代码

#include <cstdio>
#include <queue>
#include <cmath>
#include <cstring>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;struct treenode {char data;treenode *left;treenode *right;
};void levelorder(treenode *root) {queue<treenode *> myq;myq.push(root);while (myq.empty() != true) {treenode *temp = myq.front();if (temp->left != NULL) {myq.push(temp->left);}if (temp->right != NULL) {myq.push(temp->right);}myq.pop();printf("%c", temp->data);}
}void preorder(treenode *root) {if (root == NULL) {return;}printf("%c", root->data);preorder(root->left);preorder(root->right);
}treenode *pre_build(int &i, char *preord) {char c = preord[i];++i;if (c == '#') {return NULL;} else {treenode *newnode = new treenode;newnode->data = c;newnode->left = pre_build(i, preord);newnode->right = pre_build(i, preord);return newnode;}
}int main() {char preord[] = "ab##cd#gf###e##";int i = 0;treenode *root = pre_build(i, preord);preorder(root);printf("\n");levelorder(root);return 0;
}

3.先序序列+中序序列建树

给定一个二叉树的先序序列和中序序列,例如abcdgfe(先序)和badfgce(中序),对应的二叉树如下图所示:
在这里插入图片描述

分析

仍然采用递归的思想:
设先序序列为preorder[n],中序序列为midorder[n]

  1. 大事化小:
    • 确定根,即树根为preorder[0],左子树为preorder[1~ pos],右子树为preorder[pos+1~ n]
    • 找到根,即查询到根preorder[0]在中序序列中的位置为pos,有midorder[0~ (pos-1)]是左子树,midorder[ (pos+1)~n]是右子树
  2. 最小问题:子树序列长度为0——>表明是空树

代码

#include <cstdio>
#include <queue>
#include <cmath>
#include <cstring>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;struct treenode {char data;treenode *left;treenode *right;
};void aftervisit(treenode *root) {if (root == NULL) {return;}aftervisit(root->left);aftervisit(root->right);printf("%c", root->data);
}treenode *rebuild(string pre, string mid) {if (pre.size() == 0) {return NULL;} else {char root_data = pre[0];int root_index = mid.find(root_data);//分割子树string pre_l = pre.substr(1, root_index);//左子树的pre序列string pre_r = pre.substr(root_index + 1);//右子树的pre序列string mid_l = mid.substr(0, root_index);//左子树的mid序列string mid_r = mid.substr(root_index + 1);//右子树的mid序列treenode *newnode = new treenode;newnode->data = root_data;newnode->left = rebuild(pre_l, mid_l);newnode->right = rebuild(pre_r, mid_r);return newnode;}
}int main() {char pre[100];char mid[100];scanf("%s\n%s", mid, pre);treenode *root = rebuild(pre, mid);aftervisit(root);return 0;
}

牛刀小试

1. 已知后序序列和中序序列,求前序序列(先自己写一遍再看代码哦)

(我也新建一个文件,重头再练一遍!)

  • 输入:badfgce(中序)、bfgdeca(后序)
  • 正确结果:abcdgfe(先序)

代码(要诚实!!自己先写一遍!!)

#include <iostream>
using namespace std;struct treenode {char data;treenode *left;treenode *right;
};void previsit(treenode *root) {if (root == NULL) {return ;}printf("%c", root->data);previsit(root->left);previsit(root->right);
}treenode *rebuild(string mid, string aft) {if (aft.size() == 0) {return NULL;} else {char root_data = aft[aft.size() - 1];int root_index = mid.find(root_data);//开始划分子树string aft_l = aft.substr(0, root_index);string aft_r = aft.substr(root_index, aft.size() - root_index - 1);string mid_l = mid.substr(0, root_index);string mid_r = mid.substr(root_index + 1);//开始构建子树treenode *root = new treenode;root->data = root_data;root->left = rebuild(mid_l, aft_l);root->right = rebuild(mid_r, aft_r);return root;}
}int main() {char mid[100];char aft[100];scanf("%s\n%s", mid, aft);treenode *root = rebuild(mid, aft);previsit(root);return 0;
}

注意,我一开始对substr的理解有误,即:将substr函数理解为substr(起始位置序号,尾后序号);(这种理解是错误的),结果会报错:c++ - ‘std::out_of_range’ what(): basic_string::substr: __pos
事实上,substr函数的两个参数是:substr(起始位置序号,分割子串的长度);
解决上述错误的过程中我查阅了两篇文章:
【c++ - ‘std::out_of_range’ what(): basic_string::substr: __pos】
【C++中substr()函数用法详解】

AC纪念墙

这两天把这个HZNU的机试题(网传)刷完了,纪念墙如下
在这里插入图片描述
我的感悟是,代码还是要多写,我其实一开始对这里面二叉树的题是有些抗拒的,因此把二叉树的题目留到了最后做,但是回顾了之前写二叉树的代码,死去的回忆重新调入脑袋里面(人脑的缺页异常处理机制哈哈哈),然后感觉也还行,不是很难,就是不练容易忘,牛刀小试时候,重新建立了一个文件,从头开始建二叉树,思路还是很流畅的!!!
我还是蛮厉害的!!!

CODING 爽!

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

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

相关文章

数据结构初阶:算法的时间复杂度和空间复杂度

什么是数据结构&#xff1f; 数据结构 (Data Structure) 是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的 数据元素的集合。 什么是算法&#xff1f; 算法 (Algorithm): 就是定义良好的计算过程&#xff0c;他取一个或一组的值为输入&#xff0c…

Linux第85步_EXTI外部中断

1、在stm32mp157d-atk.dts文件中添加“led0”和“key0”节点 打开虚拟机上“VSCode”&#xff0c;点击“文件”&#xff0c;点击“打开文件夹”&#xff0c;点击“zgq”&#xff0c;点击“linux”&#xff0c;点击“atk-mp1”&#xff0c;点击“linux”&#xff0c;点击“my_l…

16.面向对象的软件测试技术

主要考点&#xff1a; 1、面向对象相关的基础概念&#xff1b;&#xff08;已经在软件工程的课程中讲过&#xff0c;要熟悉UML图&#xff0c;知道类和类之间的关系&#xff0c;这些知识也可能结合到下午题考察&#xff09; 2、面向对象的软件测试技术&#xff1b;&#xff08;大…

Keil MDK 5.37 及之后版本 安装 AC5(ARMCC) 编译器详细步骤

由于 Keil 5.37 及之后版本不再默认安装 AC5(ARMCC) 编译器&#xff0c;这就会导致由 AC5 编译的工程无法正常编译&#xff0c;往往输出窗口会提示以下信息&#xff1a;*** Target ‘STM32xxxx‘ uses ARM-Compiler ‘Default Compiler Version 5‘ which is not available. —…

苹果应用上架流程解析

苹果上架要求是苹果公司对于提交应用程序到苹果商店上架的要求和规定。这些要求主要是为了保证用户体验、应用程序的质量和安全性。以下是苹果上架要求的详细介绍&#xff1a;1. 应用程序的内容和功能必须符合苹果公司的规 苹果上架要求是苹果公司对于提交应用程序到苹果商店上…

用Python标准GUI库Tkinter绘制分形图

用Python标准GUI库Tkinter绘制分形图 分形图是一种通过迭代规则生成自相似图案的艺术形式。 分形图包括曼德勃罗集、科赫曲线、谢尔宾斯基三角等代码等。 Tkinter是Python的标准GUI库&#xff0c;可以用于创建窗口、控件和其他图形界面元素。绘制分形图像&#xff0c;如曼德…

iPhone设备中如何分析和解决应用程序崩溃日志的问题

​ 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么&#xff1f; 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分析 总结 摘要 本文介绍了如何在iPhone设备中查看崩溃日志&#xff0c;以便调查崩溃的原因。我们将展示三种不同的…

从零开始 使用OMNET++结合VEINS,INET和SUMO的联合仿真

背景知识 当我们探索未来的交通系统和智能交通解决方案时&#xff0c;车辆到一切&#xff08;Vehicle-to-Everything, V2X&#xff09;通信技术显得尤为重要。V2X是指在车辆与车辆&#xff08;V2V&#xff09;、车辆与基础设施&#xff08;V2I&#xff09;、车辆与行人&#x…

0 决策树基础

目录 1 绪论 2 模型 3 决策树面试总结 1 绪论 决策树算法包括ID3、C4.5以及C5.0等&#xff0c;这些算法容易理解&#xff0c;适用各种数据&#xff0c;在解决各种问题时都有良好表现&#xff0c;尤其是以树模型为核心的各种集成算法&#xff0c;在各个行业和领域都有广泛的…

优化页面加载时间:改善用户体验的关键

✨✨ 祝屏幕前的您天天开心&#xff0c;每天都有好运相伴。我们一起加油&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 一、为什么页面加载时间重要&#xff1f; 二、如何减少页面加载时间&#xff1f; …

干部任免管理系统开发(二) 数据库表的建设

前言: 字段照搬Lrmx文件内容 数据库表字段的设计基本上就是照搬Lrmx文件内容,没有什么过多的技术含量,也可以根据自己的需要对照Lrmx文件的格式自己去定义字段了。 软件的功能截图如下&#xff1a;核心就是能够任免审批表内容读取到数据库&#xff0c;生成lrmx和word格式方便做…

SiteSucker Pro mac 5.3.2激活版 网站扒站神器

SiteSucker是一个Macintosh应用程序&#xff0c;可以从互联网自动下载网站。它通过将站点的网页、图像、PDF、样式表和其他文件异步复制到本地硬盘驱动器&#xff0c;复制站点的目录结构来实现此目的。只需输入一个URL&#xff08;统一资源定位器&#xff09;&#xff0c;按回车…

JavaScript 入门指南(三)BOM 对象和 DOM 对象

BOM 对象 BOM 简介 BOM&#xff08;browser Object Model&#xff09;即浏览器对象模型BOM 由一系列对象组成&#xff0c;是访问、控制、修改浏览器的属性的方法BOM 没有统一的标准&#xff08;每种客户端都可以自定标准&#xff09;。BOM 的顶层是 window 对象 window 对象 …

习题2-5 求平方根序列前N项和

本题要求编写程序&#xff0c;计算平方根序列 的前N项之和。可包含头文件math.h&#xff0c;并调用sqrt函数求平方根。 输入格式: 输入在一行中给出一个正整数N。 输出格式: 在一行中按照“sum S”的格式输出部分和的值S&#xff0c;精确到小数点后两位。题目保证计算结果不…

1.10 类、方法、封装、继承、多态、装饰器

一、介绍类 类(class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例 实例化&#xff1a;创建一个类的实例&#xff0c;类的具体对象。 对象&#xff1a;通过类定义的数据结构实例。对象包括两个数据成员&#x…

物联网实战--入门篇之(六)嵌入式-WIFI驱动(ESP8266)

目录 一、WIFI简介 二、基础网络知识 三、思路讲解 四、代码分析 4.1 状态机制 4.2 客户端连接 4.3 应用数据接收处理 4.4 数据发送 4.5 主函数调用 4.6 网络连接ID分配 五、总结 一、WIFI简介 WIFI在我们生活中太常见了&#xff0c;手机电脑都可以用WiFi连接路由器进行上…

2024品牌私域运营:「去中心化」正在成为企业决胜关键

越来越多的品牌选择以DTC模式与消费者互动和销售。通过与消费者建立紧密联系&#xff0c;不仅可提供更具成本效益的规模扩张方式&#xff0c;还能控制品牌体验、获取宝贵的第一方数据并提升盈利能力。许多企业采取的DTC私域策略以交易为中心的方法往往导致了成本上升和运营复杂…

【Blockchain】区块链浏览器 | 以太坊Etherscan比特币Blockchain门罗币Monero

区块链浏览器概述 区块链浏览器是一种软件,它使用API(应用程序编程接口)和区块链节点从区块链中提取各种数据&#xff0c;然后使用数据库来排列搜索到的数据&#xff0c;并以可搜索的格式将数据呈现给用户。 用户的输入是资源管理器上的可搜索项&#xff0c;然后通过数据库上…

市场复盘总结 20240329

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 60% 最常用…

STM32系统结构及总线介绍

1、学习路径 STM32中文参考手册中的第二章存储器和总线构架 2、系统架构&#xff08;中等容量芯片stm32f103c8&#xff09; 在小容量、中容量和大容量产品中,主系统由以下部分构成: 四个驱动单元&#xff1a; CortexTM-M3内核DCode总线&#xff08;D-bus&#xff09;&#…