当前位置: 首页 > news >正文

【二叉树】练习题终章

二叉树的销毁

void BTreeDestroy(BTNode* root)
{if (root == NULL)return;BTreeDestroy(root->left);BTreeDestroy(root->right);free(root);
}

递归展示图在这里插入图片描述
使用后序销毁,如果用前序销毁的话,就会找不到根对应的子树的地址.下面就不能被销毁了,所以从子树开始销毁,自下而上的销毁方式,采用后序.

二叉树的遍历

二叉树的遍历
题目描述
在这里插入图片描述

代码实现

#include <stdio.h>
#include <stdlib.h>
typedef struct BinaryTreeNode {char data;struct BinaryTreeNode* left;struct BinaryTreeNode* right;
} BTNode;
BTNode* BinaryTreeCreate(char*a,int*pi)
{if(a[*pi]=='#'){(*pi)++;return NULL;}BTNode* root=(BTNode*)malloc(sizeof(BTNode));if(root==NULL){perror("malloc fail");}root->data=a[(*pi)++];root->left=BinaryTreeCreate(a,pi);root->right=BinaryTreeCreate(a,pi);return root;
}
void  InOrder(BTNode* root)
{if(root==NULL)
return ;
InOrder(root->left);
printf("%c ",root->data);
InOrder(root->right);}
int main() {char a[100];scanf("%s",a);int i = 0;BTNode*bk=BinaryTreeCreate(a, &i);InOrder(bk);}

思路分析:
我们可以根据给定的字符串进行还原二叉树,按照先序遍历,所以还原出来为下图的样子
在这里插入图片描述因为要输入一段字符串,从字符串中读取到二叉树中,对应的操作为

    char a[100];scanf("%s",a);

由于要构建二叉树,先构建一个二叉树节点的结构体

typedef struct BinaryTreeNode {char data;//节点数据struct BinaryTreeNode* left;//左子树结点地址struct BinaryTreeNode* right;//右子树结点地址
} BTNode;

定义一个创建二叉树的函数

BTNode* BinaryTreeCreate(char*a,int*pi)

函数的返回值为树节点的地址,参数分别为要构建二叉树的字符串,第二个参数是传递构建字符串数组的下标,为了防止栈销毁时,参数被销毁,所以传下标的地址过去,下标从0开始.
如果a字符串的第一个元素开始构建二叉树,当遇到‘#’,相当与构建二叉树的NULL,return NULL即可,并且a数组下标加到下一个元素,当遇到一个非‘#’时,malloc一个树的结点,地址保存在root里面,root->data=a[(*pi)++];将数据写进该节点,(*pi)++表示赋值后,下标指向下一个元素,递归调用左子树和右子树,同理创建子树,然后返回创建好根的地址,然后通过中序遍历打印即可.

相同的树

相同的树
题目描述
在这里插入图片描述
代码展示

bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
if(p==NULL&&q==NULL)
return true;
if(p==NULL||q==NULL)
return false;
if(p->val!=q->val)
return false;return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);   
}

代码分析:当两个树为空树时,两个为相同的树,返回true,当程序经过这个判断条件,并且没有结束,说明两颗树不同时为空 ,如果一个树为空,另一个树不为空,则两颗树不相等,返回false;
如果程序还没有结束,则说明两个树的该节点都不为空,判断两个节点存在后,如果两个节点不相等,则返回false,如果程序还没有结束,则说明两颗树的根节点相等,接下来递归判断左子树和右子树,因为要判断的是两颗树是否相同,则必须保证制左子树相同且右子树相同,二者是&&的关系。

翻转二叉树

翻转二叉树
题目描述
在这里插入图片描述
代码展示

struct TreeNode* invertTree(struct TreeNode* root) {
if(root==NULL)
return NULL ;
struct TreeNode* left=invertTree(root->left);
struct TreeNode* right=invertTree(root->right);
root->left=right;
root->right=left;
return root;}

递归遍历图
在这里插入图片描述
根据递归图我们可以看到,先发生交换的是两个空节点,然后进行,1,3的交换,然后是6和9的交换.
在这里插入图片描述
交换后如上图所示.
然后就是2,7的交换
在这里插入图片描述
注意:本质上是根节点的左右子树地址的交换.

二叉树的层序遍历

层序遍历:除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历.
在这里插入图片描述

层序遍历的接口

// 层序遍历
void LevelOrder(BTNode* root);

实现方法:使用队列这种结构,当队列中没有数据时,我们可以先入队列一个堆顶数据,这里着重强调入队的元素为树节点的地址,然后队列不为空.先保存队列中元素的地址,然后出队列,并且打印这个出队列的元素,由于已经保存好堆顶节点的地址,所以我们可以找到对应的子树,当出一个根节点时,如果根节点的左右子树不为空地话,就将左右子树节点的地址入队列,总结是,先入队列一个,当这个元素出队列时,依次入队列他的左子树和右子树的地址,在出这个左子树时,同理,将他的左右子树依次入队列.
图片演示
在这里插入图片描述
代码展示
首先是队列的功能函数

typedef struct QListNode
{struct QListNode* next;//保存结点的下一个结点的地址int  data;//该节点的数据
}QNode;
typedef struct Queue
{QNode* front;QNode* tail;
}Queue;//定义一个队列结构体,指向队列的前结点和尾结点
// 初始化队列
void QueueInit(Queue* q)
{assert(q);q->front = q->tail = NULL;//头节点尾结点置为NULL}
// 队尾入队列
void QueuePush(Queue* q, int data)
{assert(q);QNode* newnode = (QNode*)malloc(sizeof(QNode));//新结点申请空间assert(newnode);//防止申请失败newnode->next = NULL;//新节点的下一个结点的地址为空,不保存newnode->data = data;//新结点的数据if (q->front == NULL)//没有一个结点{q->front = q->tail = newnode;//就让指向头节点和指向尾结点的指针指向新结点}else//有结点{q->tail->next = newnode;//新结点尾插到后面q->tail = newnode;//移动指向尾结点的指针到队列末尾结点,也就是新结点}}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{return q->front == NULL;//如果没有结点,则q->front==NULL,表达式成立返回1,表明队列为空}// 队头出队列
void QueuePop(Queue* q)
{assert(q);assert(!QueueEmpty(q));//防止队列为空在出数据if (q->front->next == NULL)//如果只有一个结点{q->front = q->tail == NULL;//那就把这个结点置空,指向头结点指针和指向尾结点的指针指向空}else{QNode* next = q->front->next;//保存下一个结点的地址free(q->front);//从头结点开始释放一个结点,也就是头删q->front = next;//指向头结点的指针移动到下一个位置}}
// 获取队列头部元素
int QueueFront(Queue* q)
{assert(q);assert(q->front);//防止头节点为空return q->front->data;//头结点数据}
// 获取队列队尾元素
int QueueBack(Queue* q)
{assert(q);assert(q->tail);//防止尾节点为空return q->tail->data;//尾节点数据}
// 获取队列中有效元素个数
int QueueSize(Queue* q)
{int size = 0;//记录元素个数变量assert(q);QNode* cur = q->front;//遍历队列的指针先指向头while (cur){size++;//遍历记数cur = cur->next;}return size;//返回有效数据个数
}
// 销毁队列
void QueueDestroy(Queue* q)
{assert(q);QNode* cur = q->front;//遍历队列的指针while (cur){QNode* next = cur->next;//保存下一个节点的地址free(cur);//释放掉当前cur指针指向当前位置的空间cur = next;//指向下一个位置}q->front = q->tail = NULL;//防止野指针}

层序遍历实现

void LevelOrder(BTNode* root)
{Queue sk;QueueInit(&sk);if (root != NULL){QueuePush(&sk,root);}while (!QueueEmpty(&sk)){BTNode* front=QueueFront(&sk);QueuePop(&sk);printf("%d ", front->data);if (front->left != NULL){QueuePush(&sk, front->left);}if (front->right != NULL){QueuePush(&sk, front->right);}}QueueDestroy(&sk);}

包含的头文件

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

判断二叉树是否为完全二叉树

在这里插入图片描述
方法:层序遍历二叉树,会出现数据都是连续的.
在这里插入图片描述
如果是这样的,则他不是完全二叉树。
如何实现,用到了层序遍历,我们当队列没数据时,先入一个堆顶节点进去,和层序遍历一样,不同的是,如果队前元素为空地话会退出判断队列为空的循环,此时检查队列种如果有非空元素,则说明该树不是完全二叉树
图示说明:
在这里插入图片描述
比如说这个例子:
在这里插入图片描述
如果修改一下:
在这里插入图片描述

代码展示

bool BTreeComplete(BTNode* root)
{Queue sk;QueueInit(&sk);if (root != NULL){QueuePush(&sk, root);}while (!QueueEmpty(&sk)){BTNode* front= QueueFront(&sk);QueuePop(&sk);if (front == NULL){break;}QueuePush(&sk, front->left);QueuePush(&sk, front->right);}while (!QueueEmpty(&sk)){BTNode* front = QueueFront(&sk);QueuePop(&sk);if (front != NULL){QueueDestroy(&sk);return false;}}QueueDestroy(&sk);return true;}

注意这里入队列的还是二叉树节点的地址,为了方便展示,上图演示我用的是元素。

相关文章:

【二叉树】练习题终章

二叉树的销毁 void BTreeDestroy(BTNode* root) {if (root NULL)return;BTreeDestroy(root->left);BTreeDestroy(root->right);free(root); }递归展示图 使用后序销毁&#xff0c;如果用前序销毁的话&#xff0c;就会找不到根对应的子树的地址.下面就不能被销毁了&…...

flutter开发实战-实现获取视频的缩略图封面video_thumbnail

flutter开发实战-实现获取视频的缩略图封面video_thumbnail 在很多时候&#xff0c;我们查看视频的时候&#xff0c;视频没有播放时候&#xff0c;会显示一张封面&#xff0c;可能封面没有配置图片&#xff0c;这时候就需要通过获取视频的缩略图来显示封面了。这里使用了video…...

Prompt Toolkit探索:打造交互式CLI应用

简介&#xff1a;prompt_toolkit 是一个 Python 的库&#xff0c;它提供了一系列功能丰富的用户界面元素&#xff0c;比如自动完成、语法高亮、多行编辑、提示等等&#xff0c;让你可以轻松地构建出功能强大的命令行工具。而且&#xff0c;这个库还被 IPython 和 pgcli 这样的知…...

【已解决】AttributeError: module ‘gradio‘ has no attribute ‘outputs‘

问题描述 AttributeError: module gradio has no attribute outputs 不知道作者用的是哪个gradio版本&#xff0c;最新的版本报错AttributeError: module gradio has no attribute outputs &#xff0c; 换一个老一点的版本会报错AttributeError: module gradio has no attribu…...

WPF Mvvm模式下面如何将事件映射到ViewModel层

前言 平常用惯了Command绑定,都快忘记传统的基于事件编程模式了,但是Commond模式里面有个明显的问题,就是你无法获取到事件源的参数。很多大聪明肯定会说,这还不简单,通过自己写控件,给控件加个自定义属性不就行了,想要啥事件就写啥事件进去,完全自主可控。但是对于写…...

C# WPF上位机开发(计算器界面设计)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 c# wpf最大的优势就是开发业务软件比较快、效率比较高。一般来说&#xff0c;它的界面和逻辑部分可以同时开发。界面的部分用xaml编写即可&#xf…...

[c]比较月亮大小

本题的难点就是分情况讨论 #include<stdio.h> int main() {int n;scanf("%d",&n);int arr2[n];int p;for(int m0;m<n-1;m){scanf("%d",&arr2[m]);//输入n个数保存到数组}if(n1)//当输入一个数据时&#xff0c;输入0&#xff0c;可以判断…...

【Java 基础】16 泛型

文章目录 什么是泛型&#xff1f;泛型的声明泛型的使用泛型方法通配符和泛型上下界1&#xff09;通配符2&#xff09;泛型上下界 泛型的好处注意事项 泛型提供了一种在编写代码时更好地 支持类型安全的机制。通过泛型&#xff0c;我们可以编写更加 通用、 灵活、 可读性高的…...

Android framework定制1-->用户无操作一段时间,自动播放客户提供的视频,用户操作后退出播放

在PowerManagerService.java中监听用户操作&#xff0c;10秒无操作则打开预置的apk播放视频&#xff0c;直接上代码&#xff1a; --- a/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.javab/frameworks/base/services/core/java/com/andr…...

Vmware17虚拟机安装windows10系统

不要去什么系统之家之类的下载镜像&#xff0c;会不好安装&#xff0c;镜像被魔改过了&#xff0c;适合真实物理机上的系统在PE里安装系统&#xff0c;建议下载原版系统ISO文件 安装vmware17pro 下载地址https://dwangshuo.jb51.net/202211/tools/VMwareplayer17_855676.rar 解…...

Golang实践录:读取yaml配置文件

本文对 yaml 文件进行解析。 下载 yaml执行 go get github.com/spf13/viper 安装。 golang 有很多库可以解释 yaml 文件。本文选用 viper 进行解析&#xff0c;执行 go get github.com/spf13/viper 安装。 yaml语法规则 yaml对大小写敏感。yaml的层级关系只能使用空格缩进&a…...

oracle sql相关语法

SQL*PLUS 在SQL*PLUS执行&#xff0c;会在执行后显示查询的执行计划和统计信息 SET AUTOTRACE ON;SELECT * FROM your_table WHERE column_name value;SET AUTOTRACE OFF;PLSQL PLSQL查询sql界面&#xff0c;鼠标右键&#xff0c;点击执行计划&#xff0c;会出现sql的执行计…...

el-table,列表合并,根据名称列名称相同的品名将其它列值相同的进行合并

el-table,列表合并,根据名称列名称相同的品名将其它列值相同的进行合并,并且不能跨品名合并 如图 用到el-table合并行的方法合并 tableSpanMethod({ row, column, rowIndex, columnIndex }) {if (column.property "materielName") {//合并商品名const _row this…...

微信小程序显示二维码?

wxml <canvas style"width: 100%;height: 100%;margin-left: 20%;" id"Canvase" type"2d"></canvas> js // pages/code/code.js Page({/*** 页面的初始数据*/data: {code: ,},/*** 生命周期函数--监听页面加载*/onLoad(options) {…...

JavaWeb开发全流程笔记

JavaWeb 前端Web开发javaScript1.JS引入2.JS基础语法3.JS函数4.JS对象 BOMDOM文档对象模型JS事件监听VueVue常用指令Vue的生命周期 AjaxAxios 前端工程化环境准备NodeJS安装和Vue-cli安装vue项目Vue组件库Element组件的使用 Vue路由Nginx打包部署 后端Web开发MavenSpringBootHT…...

LLM;超越记忆《第 2 部分 》

一、说明 在这篇博客中&#xff0c;我深入研究了将大型语言模型&#xff08;LLM&#xff09;提升到基本记忆之上的数学框架。我们探索了动态上下文学习、连续空间插值及其生成能力&#xff0c;揭示了 LLM 如何理解、适应和创新超越传统机器学习模型。 LLM代表了人工智能的重大飞…...

Python中的加法测试题实现

随机生成5道10以内的加法测试题&#xff0c;用户在10秒内使用键盘输入答案。完成全部5道答题之后&#xff0c;计算机生成答题记录报告&#xff0c;并对答题情况进行分析&#xff0c;显示“答对了”&#xff0c;或“答错了”、并显示正确答案。如果未能按时完成&#xff0c;则显…...

使用gcloud SDK 管理和部署 Cloud run service

查看cloud run 上的service 列表&#xff1a; gcloud run services list > gcloud run services listSERVICE REGION URL LAST DEPLOYED BY LAST DEPL…...

JS逆向-mytoken之code参数

前言 本文是该专栏的第60篇,后面会持续分享python爬虫干货知识,记得关注。 本文以mytoken为例,通过js逆向获取其code参数的生成规律。具体的“逆向”思路逻辑,笔者将会详细介绍每个步骤,并且将在正文结合“完整代码”进行详细说明。 接下来,跟着笔者直接往下看正文详细…...

第九节HarmonyOS 常用基础组件4-Button

一、Button Button组件主要用来响应点击操作&#xff0c;可以包含子组件。 示例代码&#xff1a; Entry Component struct Index {build() {Row() {Column() {Button(确定, { type: ButtonType.Capsule, stateEffect: true }).width(90%).height(40).fontSize(16).fontWeigh…...

常用数据预处理方法 python

常用数据预处理方法 数据清洗缺失值处理示例删除缺失值插值法填充缺失值 异常值处理示例删除异常值替换异常值 数据类型转换示例数据类型转换在数据清洗过程中非常常见 重复值处理示例处理重复值是数据清洗的重要步骤 数据转换示例 数据集成示例数据集成是将多个数据源合并为一…...

【无标题】AttributeError: module ‘gradio‘ has no attribute ‘outputs‘

问题描述 AttributeError: module gradio has no attribute outputs 不知道作者用的是哪个gradio版本&#xff0c;最新的版本报错AttributeError: module gradio has no attribute outputs &#xff0c; 换一个老一点的版本会报错AttributeError: module gradio has no attribu…...

无人机助力电力设备螺母缺销智能检测识别,python基于YOLOv7开发构建电力设备螺母缺销小目标检测识别系统

传统作业场景下电力设备的运维和维护都是人工来完成的&#xff0c;随着现代技术科技手段的不断发展&#xff0c;基于无人机航拍飞行的自动智能化电力设备问题检测成为了一种可行的手段&#xff0c;本文的核心内容就是基于YOLOv7来开发构建电力设备螺母缺销检测识别系统&#xf…...

动态页面技术的发展与应用

jsp 静态页面&#xff1a;web诞生后的html文档&#xff0c;不论多少次访问都是同一份html文档或者是其他的什么文档&#xff0c;所以说是”静态“的。 虽然js能让页面产生互动&#xff0c;但是不论什么人访问&#xff0c;看到的都是放在服务器的那一份写死的文件/文档activexa…...

1-算法基础-编程基础

1.基本数据类型 char ch A; char s[] "hello";2.const定义常量 const int N 1e5 9;//const定义常量&#xff0c;后续不可被修改 int a[N];3.万能头文件 C11等可用 #include<bits/stdc.h> using namespace std;4.typedef typedef long long kk; kk a[20…...

HarmonyOS应用开发——程序框架UIAbility、启动模式与路由跳转

前言 UIAbility简单来说就是一种包含用户界面的应用组件&#xff0c;用于和用户进行交互。每一个UIAbility实例&#xff0c;对应于一个最近任务列表中的任务。 一个应用可以有一个UIAbility&#xff0c;也可以有多个UIAbility。一个UIAbility可以对应于多个页面&#xff0c;建议…...

node.js-连接SQLserver数据库

1.在自己的项目JS文件夹中建文件&#xff1a;config.js、mssql.js和server.js以及api文件夹下的user.js 2.在config.js中封装数据库信息 let app {user: sa, //这里写你的数据库的用户名password: ,//这里写数据库的密码server: localhost,database: medicineSystem, // 数据…...

目标检测YOLO系列从入门到精通技术详解100篇-【图像处理】图像预处理方法

目录 前言 知识储备 Opencv图像操作 几个高频面试题目 为什么需要图像算法? 算法原理...

Android drawable layer-list右上角红点,xml布局实现,Kotlin

Android drawable layer-list右上角红点&#xff0c;xml布局实现&#xff0c;Kotlin <?xml version"1.0" encoding"utf-8"?> <layer-list xmlns:android"http://schemas.android.com/apk/res/android"><itemandroid:id"id…...

网络虚拟化场景下网络包的发送过程

网络虚拟化有和存储虚拟化类似的地方&#xff0c;例如&#xff0c;它们都是基于 virtio 的&#xff0c;因而在看网络虚拟化的过程中&#xff0c;会看到和存储虚拟化很像的数据结构和原理。但是&#xff0c;网络虚拟化也有自己的特殊性。例如&#xff0c;存储虚拟化是将宿主机上…...