追梦之旅【数据结构篇】——详解C语言实现二叉树

news2024/11/23 21:15:18

详解C语言实现二叉树~😎

  • 前言🙌
  • 什么是二叉树?
  • 二叉树的性质总结:
  • 整体实现内容分析💞
    • 1.头文件的编写:🙌
    • 2.功能文件的编写:🙌
      • 1)前序遍历的数值来创建树——递归函数实现 😊
      • 2)求树的高度函数实现 😊
      • 3)求叶子数函数实现 😊
      • 4)求树的总结点个数函数实现 😊
      • 5)前序遍历二叉树实现 😊
      • 6)中序遍历二叉树实现 😊
      • 7)后序遍历二叉树实现 😊
      • 8)删除二叉树函数实现 😊
    • 3.测试文件编写::🙌
  • 总结撒花💞

追梦之旅,你我同行

   
😎博客昵称:博客小梦
😊最喜欢的座右铭:全神贯注的上吧!!!
😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主!

😘博主小留言:哈喽!😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不多说,文章推上!欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘
在这里插入图片描述

前言🙌

    哈喽各位友友们😊,我今天又学到了很多有趣的知识现在迫不及待的想和大家分享一下!😘我仅已此文,手把手带领大家详解C语言实现二叉树~ 利用二叉链式存储结构来完成二叉树的实现,并完成叶子高度,前序遍历生成树,叶节点的个数,结点总数,前序遍历,中序遍历,后序遍历,销毁树。都是精华内容,可不要错过哟!!!😍😍😍

什么是二叉树?

满足以下两个条件的树就是二叉树:

  • 本身是有序树;
  • 树中包含的各个节点的度不能超过 2,即只能是 0、1 或者 2;

二叉树的性质总结:

  • 二叉树中,第 i 层最多有 2^( i-1)个结点。
  • 如果二叉树的深度为 K,那么此二叉树最多有 2^K-1 个结点。
  • 二叉树中,终端结点数(叶子结点数)为 n0,度为 2 的结点数为 n2,则 n0=n2+1。

二叉树又可以分类为许多不同的二叉树:
在这里插入图片描述

整体实现内容分析💞

  • 利用二叉链式存储结构来完成二叉树的实现,并完成叶子高度,前序遍历生成树,叶节点的个数,结点总数,前序遍历,中序遍历,后序遍历,销毁树
  • 采用递归的思想,先是malloc开辟结点空间,然后给结点赋值,然后递归左子树然后递归右子树。这里用*表示空。最后返回生成的root指针的地址求高度,采用后序遍历的思想
  • 相当于求左右子树结点高度的最大值。每次递归加1就是计算结点数。求叶子总数时先求出左子树的叶子数再加上右子树的叶子数。求总结点数时这里直接递归计算出左子树和右子树的总结点数,每次加1表示遍历的节点数计算。然后就是前中后序的实现,这里也是用到递归的思想,最后便是将数销毁掉,malloc生成的空间要用free手动销毁。

1.头文件的编写:🙌

头文件的编写的整体思路分析:

这里用的是二叉链式存储的实现。首先是定义结构体,然后是对求叶子高度,前序遍历生成树,叶节点的个数,结点总数,前序遍历,中序遍历,后序遍历,销毁树。

#pragma once
#include"stdio.h"
#include"stdlib.h"
typedef int datatype;
typedef struct node
{
	datatype data;
	struct node* lchild, * rchild;
}tree;
tree* Creatbitree();
int Depthbitree(tree* T);
int Leaf_count(tree* T);
int Countbitree(tree* T);
int Preorder(tree* T);
int Inorder(tree* T);
int Postorder(tree* T);
tree* Delete(tree* T);

2.功能文件的编写:🙌

1)前序遍历的数值来创建树——递归函数实现 😊

编写的整体思路分析:

采用递归的思想,先是malloc开辟结点空间,然后给结点赋值,然后递归左子树然后递归右子树。这里用*表示空。最后返回生成的root指针的地址

#include"BinaryTree.h"
tree* Creatbitree()//前序遍历的数值来创建树——递归 
{
	char ch;
	tree* root;
	scanf("%c", &ch);//用于接收输入的数值 
	if (ch == '*') return NULL;//用*来判断是否为空 
	else {
		root = (tree*)malloc(sizeof(tree));
		root->data = ch;//赋值 
		root->lchild = Creatbitree();//左子树 
		root->rchild = Creatbitree();//右子树 
	}
	return root;
}

2)求树的高度函数实现 😊

编写的整体思路分析:

这里求高度,采用后序遍历的思想。相当于求左右子树结点高度的最大值。每次递归加1 就是计算结点数。

int Depthbitree(tree* T)//测量树的深度 
{
	if (T == NULL) return 0;
	else {
		int leftheighter = Depthbitree(T->lchild);
		int rightheighter = Depthbitree(T->rchild);
		return (leftheighter > rightheighter ? leftheighter + 1 : rightheighter + 1);
	}
}

3)求叶子数函数实现 😊

编写的整体思路分析:

代码上已表明算法思想,先求出左子树的叶子数再加上右子树的叶子数。

int Leaf_count(tree* T)//测量叶子的数量 
{
	if (T == NULL) return 0;
	else if (!T->lchild && !T->rchild)//如果左右结点都为空则他就是叶子结点 
		return 1;
	else return Leaf_count(T->lchild) + Leaf_count(T->rchild);
}

4)求树的总结点个数函数实现 😊

编写的整体思路分析:

这里直接递归计算出左子树和右子树的总结点数,每次加1表示遍历的节点数计算。

int Countbitree(tree* T) //测量总的结点个数
{
	if (T == NULL)
		return 0;
	else {
		return  Countbitree(T->lchild) + Countbitree(T->rchild)+1;
	}
}


5)前序遍历二叉树实现 😊

int Preorder(tree* T)//前序遍历序列 (根左右) 
{
	if (T == NULL)
		return 0;
	else {
		printf("%c  ", T->data);//先输出根节点 
		Preorder(T->lchild);
		Preorder(T->rchild);
	}
}

6)中序遍历二叉树实现 😊

int Inorder(tree* T)//中序遍历序列 (左根右) 
{
	if (T == NULL)
		return 0;
	else {
		Inorder(T->lchild);//先输出左孩子 
		printf("%c  ", T->data);
		Inorder(T->rchild);
	}
}

7)后序遍历二叉树实现 😊

int Postorder(tree* T)//后序遍历序列 (左右根) 
{
	if (T == NULL)
		return 0;
	else {
		Postorder(T->lchild);//先输出左孩子 
		Postorder(T->rchild);
		printf("%c  ", T->data);
	}
}


8)删除二叉树函数实现 😊

tree* Delete(tree* T)//删除树 
{
	if (T->lchild)
		Delete(T->lchild);
	else if (T->rchild)
		Delete(T->rchild);
	else
		free(T);
}

3.测试文件编写::🙌


#define _CRT_SECURE_NO_WARNINGS 1
#include"BinaryTree.h"

main()
{
	tree* T;
	T = (tree*)malloc(sizeof(tree));
	T->lchild = NULL;
	T->rchild = NULL;
	printf("请输入树的前序遍历序列\n");
	T = Creatbitree();
	int n = Depthbitree(T);
	int m = Leaf_count(T);
	int l = Countbitree(T);
	printf("树创建完成\n");
	printf("前序输出为\n");
	printf("\t\t");
	Preorder(T);
	printf("\n中序输出为\n");
	printf("\t\t");
	Inorder(T);
	printf("\n后序输出为\n");
	printf("\t\t");
	Postorder(T);
	
	
	printf("\n高度%d\n叶子%d\n总结点%d\n", n, m, l);
	Delete(T);
	printf("删除成功");
}

功能测试结果展示图:

在这里插入图片描述

总结撒花💞

   本篇文章旨在分享详解C语言实现二叉树。希望大家通过阅读此文有所收获本次主要是对二叉树的实现,这里只要用到的思想是递归,这也是难点所在。这就要需要画图帮忙辅助理解,递归的具体每一步是如何执行的需要分析清楚。在创建树的时候可以采用前序遍历思想创建,这种思想创建是比较好理解的,也可以用其他思想创建,相对比较难理解一点。以及区分好前中后序遍历的思想,然后再编写代码。
   😘如果我写的有什么不好之处,请在文章下方给出你宝贵的意见😊。如果觉得我写的好的话请点个赞赞和关注哦~😘😘😘

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

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

相关文章

IGKBoard(imx6ull)-Input设备编程之按键控制

文章目录1- input子系统介绍2- input事件目录(1)struct input_event 结构体(2)type(事件类型):(3)code(事件编码)(4)value…

【华为OD机试模拟题】用 C++ 实现 - 九宫格按键输入(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 去重求和(2023.Q1) 文章目录 最近更新的博客使用说明九宫格按键输入题目输入输出示例一输入输出说明示例二输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高…

webp格式转换成png怎么转

相对于png 图片,webp比png小了45%,但是缺点是你压缩的时候需要的时间更久了;优点是体积小巧;缺点是兼容性不太好, 只有opera,和chrome支持,不仅如此在后期的编辑修改上也很多软件无法打开。所以我们通常要将webp格式转…

9.1 IGMPv1实验

9.4.1 IGMPv1 实验目的 熟悉IGMPv1的应用场景掌握IGMPv1的配置方法实验拓扑 实验拓扑如图9-7所示: 图9-7:IGMPv1 实验步骤 (1)配置IP地址 MCS1的配置 MCS1的IP地址配置如图9-8所示: 图9-8:MCS1的配置 …

xgboost学习-XGBoost的智慧

文章目录一、选择弱评估器:重要参数booster二、XGB的目标函数:重要参数objective三、求解XGB的目标函数四、参数化决策树 alpha,lambda五、寻找最佳树结构:求解 ω与T六、寻找最佳分枝:结构分数之差七、让树停止生长&a…

redis(10)事务和锁机制

Redis事务定义 Redis 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 Redis 事务的主要作用就是串联多个命令防止别的命令插队。 Multi、Exec、discard Redis 事务中…

【数据挖掘实战】——应用系统负载分析与容量预测(ARIMA模型)

项目地址:Datamining_project: 数据挖掘实战项目代码 目录 一、背景和挖掘目标 1、问题背景 2、传统方法的不足 2、原始数据 3、挖掘目标 二、分析方法与过程 1、初步分析 2、总体流程 第一步:数据抽取 第二步:探索分析 第三步&a…

【华为OD机试模拟题】用 C++ 实现 - 内存池(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 去重求和(2023.Q1) 文章目录 最近更新的博客使用说明内存池题目输入输出示例一输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:…

C++【string类用法详细介绍string类模拟实现解析】

文章目录string 类用法介绍及模拟实现一、string介绍二、string类常用接口1. string类对象的常见构造接口2.string类对象的常见容量接口3.string类对象的常见修改接口4. string类对象的常见访问及遍历接口5.string其他接口1.不常用查找接口2.字符替换3.字符串拼接4.字符串排序5…

纯x86汇编实现的多线程操作系统实践 - 第三章 BSP的守护执行

本章我们将详细讲解BSP剩下的执行代码,它们被安排在bp_32.asm文件中。bp_32.asm主要完成以下功能:系统中断初始化加载字符图形数据到内存区域将AP的启动代码和32位保护模式下的代码分别加载到内存中显示主界面以及系统启动信息向所有AP群发启动命令进入守…

linux 解压.gz文件 报错 gzip:stdin:not in gzip format(已解决)

目录 1、问题: 2、分析原因 3、解决办法 1、问题: 在解压一个以【.gz】(注意不是.tar.gz)结尾的压缩包时,遇到报错 【gzip:stdin:不是gzip格式】 翻译一下问题:【gzip:st…

纯x86汇编实现的多线程操作系统实践 - 第一章 系统整体结构说明

现代CPU都是多核系统,拥有多个执行内核(即计算引擎),可并发执行不同的代码。在CPU众多的执行内核中,有一个为主执行内核(BSP),在CPU上电后,该主执行内核会率先启动&#…

lighthouse-自定义Gatherer与Audits

这篇文章是Lighthouse的后续,之前介绍了 lighthouse的介绍和基本使用方法 Lighthouse组合Puppeteer检测页面 这两篇文章,在这两篇文章中介绍了lighthouse的整体架构和基本运行的逻辑,lighthouse默认也采集了足够丰富的数据供我们去分析页面的…

都在用 AI 生成美少女,而我却。。。

最近 AI 画画特别的火,你能从网上看到非常多好看的图片,于是我就开始了我的安装之旅,我看到的图是这样的。这样的。还有这样的。然后我就开始了我的 AI 安装生成计划。安装环境首先我们需要安装 Python 环境,因为这个需要显卡&…

NCRE计算机等级考试Python真题(二)

第二套试题1、关于算法的描述,以下选项中错误的是A.算法具有可行性、确定性、有穷性的基本特征B.算法的复杂度主要包括时间复杂度和数据复杂度C.算法的基本要素包括数据对象的运算和操作及算法的控制结构D.算法是指解题方案的准确而完整的描述正确答案: …

Java基础之日志

2.日志 2.1概述【理解】 概述 程序中的日志可以用来记录程序在运行的时候点点滴滴。并可以进行永久存储。 日志与输出语句的区别 输出语句日志技术取消日志需要修改代码,灵活性比较差不需要修改代码,灵活性比较好输出位置只能是控制台可以将日志信息写…

用于C++的对象关系映射库—YB.ORM

1 介绍YB.ORM YB.ORM 旨在简化与关系数据库交互的 C 应用程序的开发。 对象关系映射器(ORM) 通过将数据库表映射到类并将表行映射到应用程序中的对象来工作,这种方法可能不是对每个数据库应用程序都是最佳的,但它被证明在需要复杂逻辑和事务处理的应用程…

不怕被AirTag跟踪?苹果Find My技术越来越普及

苹果的 AirTag 自推出以来,如何有效遏制用户用其进行非法跟踪,是摆在苹果面前的一大难题。一家为执法部门制造无线扫描设备的公司近日通过 KickStarter 平台,众筹了一款消费级产品,可帮助用户检测周围是否存在追踪的 AirTag 等设备…

Spring中的FactoryBean 和 BeanFactory、BeanPostProcessor 和BeanFactoryPostProcessor解析

文章目录FactoryBean 和 BeanFactory后置处理器BeanPostProcessor 和 BeanFactoryPostProcessorBeanPostProcessorBeanFactoryPostProcessorFactoryBean 和 BeanFactory BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的…

python元编程详解

什么是元编程 软件开发中很重要的一条原则就是“不要重复自己的工作(Don’t repeat youself)”,也就是说当我们需要复制粘贴代码时候,通常都需要寻找一个更加优雅的解决方案,在python中,这类问题常常会归类…