二叉树的增删查改

本节复习二叉树的增删查改, 二叉树的知识相对于前面的循序表, 链表, 以及栈和队列都要多一些。 同时二叉树的增删查改理解起来相对来说要困难一些。 本节来好好复习一下二叉树的增删查改。

目录

准备文件

创建结构体蓝图

二叉树的前序遍历

二叉树的后序遍历

二叉树的中序遍历

二叉树的节点个数

二叉树的叶子节点个数

二叉树的深度

判断二叉树是否为平衡二叉树

二叉树节点销毁


准备文件

首先准备好三个文件:

一个文件用于main.c调试, 一个文件用于二叉树函数的声明, 还有一个.c文件用于二叉树函数的实现。 

创建结构体蓝图

首先包含一下头文件和重新定义一下我们要保存的数据类型。 这样做是为了便于维护我们的代码

///二叉树的增删查改/
#include<stdio.h>
#include<stdlib.h>
#include"Queue.h"
#include<assert.h>


typedef int TNDataType;

然后创建结构体

///二叉树的增删查改/
#include<stdio.h>
#include<stdlib.h>
#include"Queue.h"
#include<assert.h>


typedef int TNDataType;

typedef struct TreeNode 
{
	struct TreeNode* left;
	struct TreeNode* right;
	TNDataType data;
}TNode;

二叉树的前序遍历

.h函数声明

///二叉树的增删查改/
#include<stdio.h>
#include<stdlib.h>
#include"Queue.h"
#include<assert.h>


typedef int TNDataType;

typedef struct TreeNode 
{
	struct TreeNode* left;
	struct TreeNode* right;
	TNDataType data;
}TNode;

///接口函数的声明///

//二叉树的前序遍历
void PrevOrder(TNode* root);

.c函数实现

//前序遍历
void PrevOrder(TNode* root) 
{

	if (root == NULL) 
	{
		return;
	}
	printf("%d ", root->data);//每一个根节点都有左子树和右子树,这三行代码的意思是先访问根节点。 
								//然后访问左子树, 再访问右子树。然后访问左右子树的时候, 又先访问根节点, 再访问该子树的左右子树
	PrevOrder(root->left);
	PrevOrder(root->right);
}

二叉树的后序遍历

.h函数声明

///二叉树的增删查改/
#include<stdio.h>
#include<stdlib.h>
#include"Queue.h"
#include<assert.h>


typedef int TNDataType;

typedef struct TreeNode 
{
	struct TreeNode* left;
	struct TreeNode* right;
	TNDataType data;
}TNode;

///接口函数的声明///

//二叉树的前序遍历
void PrevOrder(TNode* root);

//二叉树的后序遍历
void PostOrder(TNode* root);

.c函数实现

//后序遍历
void PostOrder(TNode* root) 
{
	if (root == NULL) 
	{
		return;
	}
	PostOrder(root->left);     //每一个根节点都有左右子树, 这三行代码的意思是先访问左右子树, 最后在访问根节点, 然后
							   //在访问每一棵左右子树的时候又先访问该子树的左右子树, 然后层层递归
	PostOrder(root->right);
	printf("%d ", root->data);

}

二叉树的中序遍历

.h函数声明

///二叉树的增删查改/
#include<stdio.h>
#include<stdlib.h>
#include"Queue.h"
#include<assert.h>


typedef int TNDataType;

typedef struct TreeNode 
{
	struct TreeNode* left;
	struct TreeNode* right;
	TNDataType data;
}TNode;

///接口函数的声明///

//二叉树的前序遍历
void PrevOrder(TNode* root);

//二叉树的后序遍历
void PostOrder(TNode* root);

//二叉树的中序遍历
void MidOrder(TNode* root);

.c函数实现

//中序遍历
void MidOrder(TNode* root)
{
	if (root == NULL) 
	{
		return;
	}
	MidOrder(root->left);		//在每一个根节点都有左右子树, 这三行代码的意思是先访问左子树, 
								//再访问根节点, 最后再访问右子树, 然后, 当访问左子树的时候, 左子树又有左子树, 就又访问
								// 该子树的左子树, 直到遇到子树为空。  
	printf("%d ", root->data);
	MidOrder(root->right);
}

二叉树的节点个数

.h函数声明

///二叉树的增删查改/
#include<stdio.h>
#include<stdlib.h>
#include"Queue.h"
#include<assert.h>


typedef int TNDataType;

typedef struct TreeNode 
{
	struct TreeNode* left;
	struct TreeNode* right;
	TNDataType data;
}TNode;

///接口函数的声明///

//二叉树的前序遍历
void PrevOrder(TNode* root);

//二叉树的后序遍历
void PostOrder(TNode* root);

//二叉树的中序遍历
void MidOrder(TNode* root);

//二叉树的层序遍历层序遍历
void LevelOrder(TNode* root);

//二叉树计算节点个数
int SumTree(TNode* root);

.c函数实现


//二叉树计算节点个数
int SumTree(TNode* root) 
{
	if (root == NULL)//空节点代表着0个节点, 所以返回0个节点 
	{
		return 0;
	}
	//代码走到这, 说明不是空节点, 不是空节点那么节点就应该加一
	return SumTree(root->left) + SumTree(root->right) + 1;//节点加1, 同时遍历左右两棵子树。
}

二叉树的叶子节点个数

.h函数声明

///二叉树的增删查改/
#include<stdio.h>
#include<stdlib.h>
#include"Queue.h"
#include<assert.h>


typedef int TNDataType;

typedef struct TreeNode 
{
	struct TreeNode* left;
	struct TreeNode* right;
	TNDataType data;
}TNode;

///接口函数的声明///

//二叉树的前序遍历
void PrevOrder(TNode* root);

//二叉树的后序遍历
void PostOrder(TNode* root);

//二叉树的中序遍历
void MidOrder(TNode* root);

//二叉树的层序遍历层序遍历
void LevelOrder(TNode* root);

//二叉树计算节点个数
int SumTree(TNode* root);

//二叉树计算叶子个数
int LeafSumTree(TNode* root);

.c函数实现


//二叉树计算叶子个数
int LeafSumTree(TNode* root) 
{
	if (root->left == NULL && root->right == NULL) 
	{
		return 1;
	}
	int left = LeafSumTree(root->left);//查看左子树
	int right = LeafSumTree(root->right);//查看右子树, 为什么要用right?因为返回值带着计算的节点个数, 如果这两个递归函数
										//不接收返回值, 那么就相当于只有遍历到叶子节点的时候返回节点,接收到叶子节点返回值
										//的节点不能继续将值返回给父节点。 
	return left + right;
}

二叉树的深度

.h函数声明

///二叉树的增删查改/
#include<stdio.h>
#include<stdlib.h>
#include"Queue.h"
#include<assert.h>


typedef int TNDataType;

typedef struct TreeNode 
{
	struct TreeNode* left;
	struct TreeNode* right;
	TNDataType data;
}TNode;

///接口函数的声明///

//二叉树的前序遍历
void PrevOrder(TNode* root);

//二叉树的后序遍历
void PostOrder(TNode* root);

//二叉树的中序遍历
void MidOrder(TNode* root);

//二叉树的层序遍历层序遍历
void LevelOrder(TNode* root);

//二叉树计算节点个数
int SumTree(TNode* root);

//二叉树计算叶子个数
int LeafSumTree(TNode* root);

//二叉树的深度
int TallTree(TNode* root);

.c函数实现


//计算树的深度
int TallTree(TNode* root) //计算树的深度的核心就是左右子树哪个高, 在他的基础上加1。
{
	if (root == NULL) 
	{
		return 0;
	}
	//
	int left = TallTree(root->left);
	int right = TallTree(root->right);
	return (left > right) ? (left + 1) : (right + 1);
}

判断二叉树是否为平衡二叉树

.h函数声明

///二叉树的增删查改/
#include<stdio.h>
#include<stdlib.h>
#include"Queue.h"
#include<assert.h>


typedef int TNDataType;

typedef struct TreeNode 
{
	struct TreeNode* left;
	struct TreeNode* right;
	TNDataType data;
}TNode;

///接口函数的声明///

//二叉树的前序遍历
void PrevOrder(TNode* root);

//二叉树的后序遍历
void PostOrder(TNode* root);

//二叉树的中序遍历
void MidOrder(TNode* root);

//二叉树的层序遍历层序遍历
void LevelOrder(TNode* root);

//二叉树计算节点个数
int SumTree(TNode* root);

//二叉树计算叶子个数
int LeafSumTree(TNode* root);

//二叉树的深度
int TallTree(TNode* root);

//判断是否为平衡二叉树
bool TreeEqual(TNode* root);

.c函数实现

//计算树的深度
int TallTree(TNode* root) //计算树的深度的核心就是左右子树哪个高, 在他的基础上加1。
{
	if (root == NULL) 
	{
		return 0;
	}
	//
	int left = TallTree(root->left);
	int right = TallTree(root->right);
	return (left > right) ? (left + 1) : (right + 1);
}

二叉树节点销毁

.h函数声明

///二叉树的增删查改/
#include<stdio.h>
#include<stdlib.h>
#include"Queue.h"
#include<assert.h>


typedef int TNDataType;

typedef struct TreeNode 
{
	struct TreeNode* left;
	struct TreeNode* right;
	TNDataType data;
}TNode;

///接口函数的声明///

//二叉树的前序遍历
void PrevOrder(TNode* root);

//二叉树的后序遍历
void PostOrder(TNode* root);

//二叉树的中序遍历
void MidOrder(TNode* root);

//二叉树的层序遍历层序遍历
void LevelOrder(TNode* root);

//二叉树计算节点个数
int SumTree(TNode* root);

//二叉树计算叶子个数
int LeafSumTree(TNode* root);

//二叉树的深度
int TallTree(TNode* root);

//判断是否为平衡二叉树
bool TreeEqual(TNode* root);

//二叉树销毁
void TreeDestroy(TNode* root);

.c函数实现


//二叉树的销毁
void TreeDestroy(TNode* root) //二叉树的销毁应该是一个后序遍历
{
	if (root->left == NULL && root->right == NULL)
	{
		free(root);
		root = NULL;
		return;
	}
	else 
	{
		if (root->left != NULL) 
		{
			TreeDestroy(root->left);

		}
		else if (root->right != NULL)
		{
			TreeDestroy(root->right);

		}
	}
	

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows PowerShell 命令行历史记录补全

Windows 命令行历史记录补全 使用 powershell 安装PSReadLine 2.1.0 Install-Module PSReadLine -RequiredVersion 2.1.0检查是否存在配置文件 Test-path $profile # 为 false 则执行命令创建 New-item –type file –force $profile编辑配置文件 notepad $profile# 输入如下…

数据结构------栈(Stack)和队列(Queue)

也是好久没写博客了&#xff0c;那今天就回归一下&#xff0c;写一篇数据结构的博客吧。今天要写的是栈和队列&#xff0c;也是数据结构中比较基础的知识。那么下面开始今天要写的博客了。 目录 栈&#xff08;Stack&#xff09; 队列&#xff08;Queue&#xff09; 喜欢就点…

从C到C++

二、从C到C 本章介绍一些C拓展的非面向对象功能。 引用&#xff08;掌握&#xff09; 1.1 概念 引用从一定程度上讲是一个指针的平替&#xff0c;几乎被所有面向对象编程语言所使用。引用相当于对某一个目标变量起”别名“。 操作引用与操作原变量完全一样。 #include <iost…

工厂模式 详解 设计模式

工厂模式 其主要目的是封装对象的创建过程&#xff0c;使客户端代码和具体的对象实现解耦。这样子就不用每次都new对象&#xff0c;更换对象的话&#xff0c;所有new对象的地方也要修改&#xff0c;违背了开闭原则&#xff08;对扩展开放&#xff0c;对修改关闭&#xff09;。…

Unity UI适配规则和对热门游戏适配策略的拆解

前言 本文会介绍一些关于UI适配的基础概念&#xff0c;并且统计了市面上常见的设备的分辨率的情况。同时通过拆解目前市面上较为成功的两款休闲游戏Royal Match和Monopoly GO(两款均为近期游戏付费榜前几的游戏)&#xff0c;大致推断出他们的适配策略&#xff0c;以供学习和参…

go并发模式之----阻塞/屏障模式

常见模式之一&#xff1a;阻塞/屏障模式 定义 顾名思义&#xff0c;就是阻塞等待所有goroutine&#xff0c;直到所有goroutine完成&#xff0c;聚合所有结果 使用场景 多个网络请求&#xff0c;聚合结果 大任务拆分成多个子任务&#xff0c;聚合结果 示例 package main ​…

Delegate动画案例(P30 5.6delegate动画)

一、ListElement&#xff0c;ListModel&#xff0c;ListView 1. ListElement ListElement 是 QML 中用于定义列表项的元素。它可以包含多个属性&#xff0c;每个属性对应列表项中的一个数据字段。通过在 ListModel 中使用 ListElement&#xff0c;可以定义一个列表的数据模型…

USB-C接口:办公新宠,一线连接笔记本与显示器

USB-C接口如今已成为笔记本与显示器连接的优选方案。无需担心正反插错&#xff0c;支持雷电4和DP视频信号输出&#xff0c;高速数据传输&#xff0c;还有最高100W的快充功能&#xff0c;真是方便又实用&#xff01; 一线连接&#xff0c;多功能融合 通过这个接口&#xff0c;你…

面试笔记系列三之spring基础知识点整理及常见面试题

目录 如何实现一个IOC容器? 说说你对Spring 的理解&#xff1f; 你觉得Spring的核心是什么&#xff1f; 说一下使用spring的优势&#xff1f; Spring是如何简化开发的&#xff1f; IOC 运行时序 prepareRefresh() 初始化上下文环境 obtainFreshBeanFactory() 创建并…

瑞_23种设计模式_外观模式

文章目录 1 外观模式&#xff08;Facade Pattern&#xff09;1.1 介绍1.2 概述1.3 外观模式的结构 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 4 jdk源码解析 &#x1f64a; 前言&#xff1a;本文章为瑞_系列专栏之《23种设计模式》的外观模式篇。本文中的部分…

如何在Windows部署TortoiseSVN客户端并实现公网连接内网VisualSVN服务端

文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控制系统&#xff0c;它与Apache Subversion&#xff08;SVN&#xff09;集成在一起&#xff0c;提供了一个用户友好的界面&#xff0c;方便用…

Flutter开发之Slider

Flutter开发之Slider 本文是关于介绍Slider相关属性的含义。 class SliderThemeData {/// slider轨道的高度 final double? trackHeight; /// 滑块滑过的轨道颜色 final Color? activeTrackColor; /// 滑块未滑过的轨道颜色 final Color? inactiveTrackColor; /// 滑块滑过…

JavaEE——简单认识JavaScript

文章目录 一、简单认识 JavaScript 的组成二、基本的输入输出和简单语法三、变量的使用四、JS 中的动态类型图示解释常见语言的类型形式 五、JS中的数组六、JS 中的函数七、JS 中的对象 一、简单认识 JavaScript 的组成 对于 JavaScript &#xff0c;其中的组成大致分为下面的…

多线程如何设计?一对多/多对一/多对多

二、14个多线程设计模式 参考原文&#xff1a;https://www.cnblogs.com/rainbowbridge/p/17443503.html single Thread 模式 一座桥只能通过一个人 Single Thread模式是一种单线程设计模式&#xff0c;即在一个应用程序中只有一个主线程、一个事件循环&#xff0c;对外只提…

【C语言基础】:深入理解指针(一)

文章目录 一、内存和地址1. 内存2. 如何理解编址 二、指针变量和地址2.1 取地址操作符(&)2.2 指针变量和解引用操作符(*)2.2.1 指针变量2.2.2 如何拆解指针变量2.2.3 解引用操作符 2.3 指针变量的大小 三、指针变量类型的意义3.1 指针的解引用3.2 指针 - 整数3.3 void*指针…

什么是物联网?

今天这篇文章写的相关内容就是带领大家了解什么是物联网&#xff0c;之前写的文章大多都是一些物联网的未来&#xff0c;行业的解决方案等&#xff1b;话不多说开始进入正题吧! 物联网(IoT)是一个包罗万象的术语&#xff0c;指的是越来越多的电子产品&#xff0c;它们不是传统的…

vue2+elementui上传照片(el-upload 超简单)

文章目录 element上传附件&#xff08;el-upload 超详细&#xff09;代码展示html代码data中methods中接口写法 总结 element上传附件&#xff08;el-upload 超详细&#xff09; 这个功能其实比较常见的功能&#xff0c;后台管理系统基本上都有&#xff0c;这就离不开element的…

计算机组成原理4-存储器的层次结构与程序访问的局部性原理

1. 磁盘 1.磁盘的结构 磁盘由盘片构成&#xff0c;每个盘片包含两面 每面由一组称为磁道的同心圆组成 每个磁道划分为一组扇区&#xff0c;扇区之间由间隙隔开 同一半径上的所有磁道组成一个柱面2.磁盘的容量 容量&#xff1a;磁盘上可以存储的最大位数。 决定因素&#xff1a…

【玩转408数据结构】线性表——双链表、循环链表和静态链表(线性表的链式表示 下)

知识回顾 在前面的学习中&#xff0c;我们已经了解到了链表&#xff08;线性表的链式存储&#xff09;的一些基本特点&#xff0c;并且深入的研究探讨了单链表的一些特性&#xff0c;我们知道&#xff0c;单链表在实现插入删除上&#xff0c;是要比顺序表方便的&#xff0c;但是…

IDEA利用鼠标调整字体大小

就可以按住ctrl和鼠标调节代码字体的大小啦&#xff01; 如果有用&#xff0c;记得给我来个赞~ 谢啦&#xff01;