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

news2024/12/25 15:04:20

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.coloradmin.cn/o/1559672.html

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

相关文章

Kubernetes(k8s)架构原理

比如在服务器上部署一个博客应用服务,但是太过受欢迎,访问量太大,应用服务经常会挂,使用自动重启工具,并且将应用服务部署在了好几个服务器上,总算抗住了。后来又上线了商城应用服务和语言应用服务,随着应用服务变多,需求也千奇百怪,有的应用服务不希望被外网访问,有…

CentOS系统下Docker的安装教程

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

[Python] 如何导出PDF文件中的图片

文章目录 一、背景说明二、代码编写三、问题3.1、如何得到图片的xref&#xff1f;3.2、xref有什么用呢&#xff1f; 四、总结 一、背景说明 最近在看一份pdf的书籍&#xff0c;其中有一些图片绘制地比较出色&#xff0c;所以就打算将其复制出来&#xff0c;以便于在需要的时候…

webGIS 之 智慧校园案例

1.引入资源创建地图 //index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content&qu…

【PyQt学习篇 · ⑮】:qrc/rcc资源系统

文章目录 qrc使用介绍rcc编译资源rcc 的安装与基本使用 编译成Python文件使用资源系统文件方式一&#xff1a;导入资源系统文件方式二&#xff1a;整合资源系统文件 qrc使用介绍 在PyQt中&#xff0c;qrc文件是一种资源文件&#xff0c;用于将应用程序所需的资源&#xff08;如…

中文Mistral模型介绍(Chinese-Mistral)——中文大语言模型

中文Mistral简介 Chinese-Mistral由清华大学地学系地球空间信息科学实验室开发。 该模型基于Mistral发布的Mistral-7B-v0.1训练得到。首先进行中文词表扩充&#xff0c;然后采用实验室提出的PREPARED训练框架&#xff08;under review&#xff09;在中英双语语料上进行增量预训…

日历插件fullcalendar【笔记】

日历插件fullcalendar【笔记】 前言版权开源推荐日历插件fullcalendar一、下载二、初次使用日历界面示例-添加事件&#xff0c;删除事件 三、汉化四、动态数据五、前后端交互1.环境搭建-前端搭建2.环境搭建-后端搭建3.代码编写-前端代码fullcalendar.htmlfullcalendar.js 4.代码…

事务传播行为Propagation

目录 背景Propagation测试程序1测试程序2分析 背景 前段时间&#xff0c;某个项目在部署时&#xff0c;被公司的一个检测拦截了&#xff0c;提示报错如下&#xff1a; Your code exists Method or Class with Transactional annotation that not use Propagation.REQUIRED.有…

算法学习——LeetCode力扣图论篇3(127. 单词接龙、463. 岛屿的周长、684. 冗余连接、685. 冗余连接 II)

算法学习——LeetCode力扣图论篇3 127. 单词接龙 127. 单词接龙 - 力扣&#xff08;LeetCode&#xff09; 描述 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> … -> sk&#xff1a; 每一对相…

macOS Catalina for mac (macos 10.15系统)v10.15.7正式版

macOS Catalina是苹果公司专为麦金塔电脑推出的桌面操作系统&#xff0c;是macOS的第16个主要版本。它继承了苹果一贯的优雅与高效&#xff0c;不仅引入了分割视图和侧边栏&#xff0c;还带来了全新的音乐和播客应用&#xff0c;极大地提升了用户体验。在隐私保护和安全性方面&…

Oracle 数据库、实例、用户、表空间、表之间的关系(新手入门)

Oracle 数据库、实例、用户、表空间、表之间的关系 数据库&#xff1a; Oracle数据库是数据的物理存储。这就包括&#xff08;数据文件ORA或者DBF、控制文件、联机日志、参数文件&#xff09;。其实Oracle数据库的概念和其它数据库不一样&#xff0c;这里的数据库是一个操作系…

python中dropna()函数的作用举例说明

在Python中&#xff0c;dropna()是一个Pandas库中的函数&#xff0c;用于从数据框&#xff08;DataFrame&#xff09;中删除包含缺失值&#xff08;NaN&#xff09;的行或列。它用于数据清洗和预处理阶段&#xff0c;以便去除缺失值&#xff0c;使数据更加规整。 dropna()函数…

软件杯 深度学习YOLOv5车辆颜色识别检测 - python opencv

文章目录 1 前言2 实现效果3 CNN卷积神经网络4 Yolov56 数据集处理及模型训练5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习YOLOv5车辆颜色识别检测 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0…

nginx的缓存和gzip

nginx的缓存 缓存的基本思想是利用客户端访问的时间局限性&#xff0c;将客户端访问过的内容做一个副本&#xff0c;在一定时间内存放到本地&#xff0c;当改数据下次被访问时&#xff0c;不必连接到后端服务器反复去查询数据&#xff0c;而是由本地保存的副本响应数据。 保存…

服务器固定IP(固定出口IP)去访问外部服务

背景 服务器上有多个IP&#xff0c;那么在服务器请求外部服务的时候&#xff0c;到底是使用哪个IP呢&#xff1f;如果要使用特定的IP去请求外部服务&#xff0c;该如何设置呢&#xff1f; 分析 遇到一个实际的场景&#xff1a; 我们产品和其他产品联调&#xff0c;我们的服务…

【A-010】基于SSH的宠物狗商城系统(含论文)

【A-010】基于SSH的宠物狗商城系统&#xff08;含论文&#xff09; 开发环境&#xff1a; Eclipse/MyEclipse、Tomcat8、Jdk1.8 数据库&#xff1a; MySQL 项目介绍&#xff1a; 在科学技术飞速发展的今天&#xff0c;互联网成为人们快速获取、发布和传递信息的重要渠道&am…

【Docker笔记01】【基础内容】

一、前言 本系列是根据 B 站 尚硅谷 Docker 视频 学习记录笔记。因为没有视频课件&#xff0c;部分内容摘自 https://www.yuque.com/tmfl/cloud/dketq0。 本系列仅为自身学习笔记记录使用&#xff0c;记录存在偏差&#xff0c;推荐阅读原视频内容或本文参考笔记。 二、Docker…

基于springboot实现房屋租赁系统项目【项目源码+论文说明】

基于springboot实现房屋租赁系统演示 摘要 社会的发展和科学技术的进步&#xff0c;互联网技术越来越受欢迎。网络计算机的生活方式逐渐受到广大人民群众的喜爱&#xff0c;也逐渐进入了每个用户的使用。互联网具有便利性&#xff0c;速度快&#xff0c;效率高&#xff0c;成本…

QT-左框选项卡软件界面框架

QT-左框选项卡软件界面框架 一、演示效果二、关键程序三、下载链接 一、演示效果 二、关键程序 #include <QTextBrowser> #include <QLabel> #include <QPushButton> #include <QSpacerItem> #include <QToolButton> #include <QDebug> #i…

浮点数(小数)在计算机中如何用二进制存储?

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/137182814 出自【进步*于辰的博客】 注&#xff1a;为了阐述更加严谨&#xff0c;本篇文章中将使…