【数据结构】二叉树的认识与实现

        

目录

二叉树的概念: 

二叉树的应用与实现: 

 二叉树实现接口:

通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树 

 二叉树节点个数​编辑

二叉树叶子节点个数 

二叉树第k层节点个数 

 二叉树查找值为x的节点​编辑

 二叉树前序遍历,中序遍历,后序遍历

层序遍历 

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

二叉树销毁 


二叉树的概念: 

        在前面的学习中我们认识了树的概念,今天的我们将学习数中比较特殊的一类:二叉树。

二叉树故名思意,这种树只存在两个分支,图形相貌如下: 

 而二叉树中又存在着特殊的两类:满二叉树和完全二叉树。

  • 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是 ,则它就是满二叉树。

     
  •  完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

二叉树的性质
1. 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有 2^(i-1)个结点。
2. 若规定根结点的层数为1,则深度为h的二叉树的最大结点数是 2^h-1。
3. 对任何一棵二叉树, 如果度为0其叶结点个数为n0, 度为2的分支结点个数为n2,则有n0= n2+1。4. 若规定根结点的层数为1,具有n个结点的满二叉树的深度,h=log(n+1) (ps: 是log以2
为底,n+1为对数)
5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有结点从0开始编号,则对于序号为i的结点有:
1. 若i>0,i位置结点的双亲序号:(i-1)/2;i=0,i为根结点编号,无双亲结点
2. 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
3. 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子

二叉树的应用与实现: 

 二叉树实现接口:

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>


// 类型的定义
typedef char BTDataType;

typedef struct BinaryTreeNode
{
	BTDataType _data;
	struct BinaryTreeNode* _left;
	struct BinaryTreeNode* _right;
}BTNode;

// 函数的声明

// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int* pi);

// 二叉树销毁
void BinaryTreeDestory(BTNode* root);

// 二叉树节点个数
int BinaryTreeSize(BTNode* root);

// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);

// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);

// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);

// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root);

// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root);

// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root);

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

// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root);

通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树 

// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{
	if (a[(*pi)] == '#')
	{
		(*pi)++;
		return NULL;
	}

	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	if (root == NULL)
	{
		perror("malloc fail!");
		return 1;
	}

	root->_data = a[(*pi)++];
	root->_left = BinaryTreeCreate(a, pi);
	root->_right = BinaryTreeCreate(a, pi);

	return root;
}

 二叉树节点个数

// 二叉树节点个数
int BinaryTreeSize(BTNode* root)
{
	return root == NULL ? 0 : BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 1;
}

二叉树叶子节点个数 

// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	if (root->_left == NULL && root->_right == NULL)
	{
		return 1;
	}

	return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}

二叉树第k层节点个数 

// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}

	if (k == 1)
	{
		return 1;
	}

	return BinaryTreeLevelKSize(root->_left, k - 1) +
		   BinaryTreeLevelKSize(root->_right, k - 1);
}

 二叉树查找值为x的节点

// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
		return NULL;

	if (root->_data == x)
		return root;

	BTNode* n1 = BinaryTreeFind(root->_left, x);
	if (n1)
	{
		return n1;
	}

	BTNode* n2 = BinaryTreeFind(root->_right, x);
	if (n2)
	{
		return n2;
	}

	return NULL;
}

 二叉树前序遍历,中序遍历,后序遍历

 

// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("null ");
		return;
	}

	printf("%c ", root->_data);
	BinaryTreePrevOrder(root->_left);
	BinaryTreePrevOrder(root->_right);
}

// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("null ");
		return;
	}

	BinaryTreeInOrder(root->_left);
	printf("%c ", root->_data);
	BinaryTreeInOrder(root->_right);
}

// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("null ");
		return;
	}

	BinaryTreePostOrder(root->_left);
	BinaryTreePostOrder(root->_right);
	printf("%c ", root->_data);
}

层序遍历 

void BinaryTreeLevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);

	if (root)
		QueuePush(&q, root);

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);

		printf("%c ", front->_data);

		if (front->_left)
			QueuePush(&q, front->_left);

		if (front->_right)
			QueuePush(&q, front->_right);
	}

	QueueDestroy(&q);
}

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

// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);

	if (root)
		QueuePush(&q, root);

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);

		if (front == NULL)
		{
			break;
		}

		QueuePush(&q, front->_left);
		QueuePush(&q, front->_right);
	}

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);

		if (front)
		{
			QueueDestroy(&q);
			return false;
		}
	}

	QueueDestroy(&q);
	return true;
}

二叉树销毁 

// 二叉树销毁
void BinaryTreeDestory(BTNode* root)
{
	// 使用后序遍历的方式考虑销毁

	if (root == NULL)
		return;

	BinaryTreeDestory(root->_left);
	BinaryTreeDestory(root->_right);
	free(root);
}

 代码完整文件:BinaryTree_implement_by_C_2024_5_27 · 阳区欠/数据结构的学习 - 码云 - 开源中国 (gitee.com)

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

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

相关文章

CCF20231201——仓库规划

CCF20231201——仓库规划 代码如下&#xff1a; #include<bits/stdc.h> using namespace std; int main() {int n,m,a[1001][11],b[1001]{0};cin>>n>>m;for(int i1;i<n;i){for(int j1;j<m;j)cin>>a[i][j];}for(int i1;i<n;i){bool foundfals…

分享免费的手机清理软件app,一款国外开发的手机清理神器,让手机再战两年!

手机内存越来越大&#xff0c;软件却越来越占地方&#xff0c;就像微信这家伙&#xff0c;轻轻松松就吃了十几个G&#xff01; 害得阿星8128G的手机&#xff0c;本来想换新的&#xff0c;结果用了这款Avast Cleanup软件&#xff0c;瞬间感觉手机还能再战两年&#xff01; 注意…

2024年云南特岗教师报名流程,超详细,明天就开始报名哦!

2024年云南特岗教师报名流程&#xff0c;超详细&#xff0c;明天就开始报名哦&#xff01;

贪心-leetcode402.移掉 K 位数字-XMUOJ符文序列

题目 思路 话不多说&#xff0c;直接上代码 代码 /*leetcode402.移掉 K 位数字-XMUOJ符文序列--JinlongW-2024/05/26单调栈贪心*/ #include<bits/stdc.h> const int N1010; char num[N],result[N],numStack[N]; int k; using namespace std;void removeKdigits( int k…

[Android]下拉刷新和上拉加载更多

示意图&#xff1a; 1.添加依赖 SwipeRefreshLayout 是一个支持下拉刷新功能的布局&#xff0c;它是 Android Support Library 或 AndroidX 库的一部分。 BaseQuickAdapter 是一个来自开源库 BRVAH (Base RecyclerView Adapter Helper) 的功能丰富的适配器&#xff0c;用于简化…

基于机器学习的一线城市租房价格预测分析与实现,实现三种算法预测

本文旨在基于机器学习方法&#xff0c;对一线城市租房价格进行预测分析&#xff0c;并使用Matplotlib可视化、随机森林、一元线性回归和多元线性模型进行模型对比。通过爬取北京链家二手房数据作为研究对象&#xff0c;探讨了租房价格与各种因素之间的关系&#xff0c;阐述了研…

【数据库基础-mysql详解之索引的魅力(N叉树)】

索引的魅力目录 &#x1f308;索引的概念&#x1f308;使用场景&#x1f308;索引的使用&#x1f31e;&#x1f31e;&#x1f31e;查看MySQL中的默认索引&#x1f31e;&#x1f31e;&#x1f31e;创建索引&#x1f31e;&#x1f31e;&#x1f31e;删除索引 站在索引背后的那个男…

Java时间类--JDK7

一、Date类 1.引言 全世界的时间&#xff0c;有一个统计的计算标准。 1884年&#xff0c;将英国格林威治时间认为是世界标准时间。 在2012年1月份后&#xff0c;由于误差太大&#xff0c;最高可达16min。 取消使用了近130年的格林威治时间&#xff0c;改用原子钟作为世界标…

Mistral AI 团队发布 Mistral-7B-Instruct-v0.3

抱抱脸上线了 Mistral-7B-v0.3 的基础版和指令微调版。 相比于Mistral-7B-v0.2&#xff0c;新版本更新如下&#xff1a; – 词汇量从 32000 扩展到 32768 – 支持 v3 分词器 – 支持函数调用 Mistral-7B-v0.3&#xff1a;网页链接 Mistral-7B-Instruct-v0.3&#xff1a;网页…

vue项目打包教程

如果是用 vue-cli 创建的项目&#xff0c;则项目目录中没有 config 文件夹&#xff0c;所以我们需要自建一个配置文件&#xff1b;在vue项目目录下创建文件 vue.config.js&#xff0c;需注意文件名称必须是 vue.config.js&#xff0c;然后在文件中插入以下代码&#xff1a; 文件…

Wireshark 搜不到字符串?

一个原因是pcap里没有这个字符串&#xff0c; 另一个原因可能是ctrlF之后&#xff0c;选择搜索的地方不对&#xff0c;或者是编码方式选择的不对。 上面图片的第一个下拉框是要搜索的一个范围&#xff0c;是在哪一个panel搜索&#xff0c;范围说明在下面这个链接有详细说明&…

数据结构:树(3)【二叉树链式结构实现】【二叉树的前序,中序,后序遍历】【求二叉树全部结点个数】【求二叉树叶子结点个数】【求二叉树的深度】【单值二叉树】

一.二叉树链式结构的实现 二叉树的链式结构的实现相对于顺序结构的实现就没有那么多的讲究了。就是普通的链表&#xff0c;只不过多了一个指向的指针。 具体结构如下&#xff1a; typedef int BTDataType; typedef struct BinaryTreeNode {BTDataType data;struct BinaryTre…

ASP+ACCESS客户管理信息系统

摘要 本文介绍了客户管理系统的实现方法。目的在于让大家共享学习和运用这一语言的体会和收获。本系统是Internet/Intranet环境下面向电子商务的客户管理&#xff0c;通过企业管理技术、电子商务和信息技术的高度集成&#xff0c;讨论了客户管理系统的系统构架、系统的工作…

深入理解python列表与字典:数据结构的选择与性能差异

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、列表与字典&#xff1a;基础数据结构的对比 二、列表&#xff1a;逐个遍历的查找方式 …

面试题·栈和队列的相互实现·详解

A. 用队列实现栈 用队列实现栈 实现代码如下 看着是队列&#xff0c;其实实际实现更接近数组模拟 typedef struct {int* queue1; // 第一个队列int* queue2; // 第二个队列int size; // 栈的大小int front1, rear1, front2, rear2; // 两个队列的首尾指针 } MyS…

生成式AI导论2024-李宏毅

生成式AI导论2024-李宏毅 第0讲&#xff1a; 课程说明第1讲&#xff1a;生成式AI是什么第2講&#xff1a;今日的生成式人工智慧厲害在哪裡&#xff1f;從「工具」變為「工具人」 第0讲&#xff1a; 课程说明 生成式AI的入门课程 第1讲&#xff1a;生成式AI是什么 生成式人…

【机器学习】基于核的机器学习算法(Kernel-based Algorithms):原理,应用与优化

&#x1f440;传送门&#x1f440; 文章引言&#x1f50d;&#x1f340;核函数的概念&#x1f680;基于核的算法原理&#x1f496;基于核的算法应用&#x1f41f;支持向量机&#xff08;SVM&#xff09;&#x1f4d5;核主成分分析&#xff08;KPCA&#xff09; &#x1f340;未…

Leetcode42题:接雨水

1.题目描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,…

ES的安装以及配置+ik分词

环境&#xff1a;windows10、ES&#xff08;8.13.3&#xff09;、Kibana&#xff08;8.13.3&#xff09;、Logstash&#xff08;8.13.3&#xff09;、ik&#xff08;8.13.3&#xff09; 1.下载安装ES Download Elasticsearch | ElasticDownload Elasticsearch or the complet…

基于物联网架构的电子小票服务系统

1.电子小票物联网架构 采用感知层、网络层和应用层的3层物联网体系架构模型&#xff0c;电子小票物联网的架构见图1。 图1 电子小票物联网架构 感知层的小票智能硬件能够取代传统的小票打印机&#xff0c;在不改变商家原有收银系统的前提下&#xff0c;采集收音机待打印的购物…