数据结构手撕--【二叉树】

news2025/7/19 13:00:18

 

目录

定义结构体:

初始化:

手动创建一个二叉树:

前序遍历:

中序遍历:

后序遍历

 二叉树节点个数:

叶子节点个数:

二叉树第k层节点个数:

二叉树的高度:

 查找值为x的节点:

二叉树的层序遍历:

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

销毁二叉树:


二叉树增删查改没有具体意义。我们主要实现搜索二叉树

特殊的二叉树---完全二叉树(堆) 适合数组结构表示  (堆结构下节更新)

对于普通二叉树我们采用 链式结构

定义结构体:

一个结构体就是一个树节点

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//链式二叉树

//定义结构体 --- 一个结构体就是一个树节点
typedef char BTDataType;
typedef struct BinaryTreeNode
{
	BinaryTreeNode* left;  //指向节点的指针 类型为节点类型
	BinaryTreeNode* right;
	BTDataType data;
}BTNode;

初始化:

  链式结构 开辟空间创建新节点

BTNode BuyNode(BTDataType x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	newnode->left = NULL;
	newnode->right = NULL;
	newnode->data = x;
	return newnode;
}

手动创建一个二叉树:

BTNode* CreatBinaryTree()
{
	BTNode* nodeA = BuyNode('A');
	BTNode* nodeB = BuyNode('B');
	BTNode* nodeC = BuyNode('C');
	BTNode* nodeD = BuyNode('D');
	BTNode* nodeE = BuyNode('E');
	BTNode* nodeF = BuyNode('F');

	nodeA->left = nodeB;
	nodeA->right = nodeC;
	nodeB->left = nodeD;
	nodeC->left = nodeE;
	nodeC->right = nodeF;
	return nodeA;
}

前序遍历:

---  根左右   打印放在最前面 再左、右递归

void PerOrder(BTNode* root)
{
	if (root == NULL)
	{
		return NULL;
	}
	printf("%c", root->data);
	PerOrder(root->left);
	PerOrder(root->right);
}

画图理解递归过程: 

中序遍历:

---  左根右  打印放在中间 先左递归 打印 再右递归

void MidOrder(BTNode* root)
{
	if (root == NULL)
	{
		return NULL;
	}
	MidOrder(root->left);
	printf("%c", root->data);
	MidOrder(root->right);
}

 

后序遍历

-- 左右根

void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		return NULL;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%c", root->data);
}

 二叉树节点个数:

为空返回0,不为空去递归左右子树,+1是递归完左右返回之后+1的,即就会算此时的root节点的数量。(下图有具体的递归过程)左+右+根(1)

int BinaryTreeSize(BTNode* root)
{
	return root == NULLL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

叶子节点个数:

到叶子返回1(不再向下递归),返回 左+右     不算根的个数

int BinaryTreeLeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	if (root->left && root->right == NULL) //在递归的过程中 走到叶子就会返回1 最后左+右即可
	{
		return 1;
	}
	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

二叉树第k层节点个数:

往下走一层k都会减一,假如要求第五层,走到第五层k=1,把1返回即可

int BinaryTreeLeaveSize(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}
	if (k == 1)
	{
		return 1;
	}
	return BinaryTreeLeaveSize(root->left, k - 1) + BinaryTreeLeaveSize(root->right, k - 1);
}

 

二叉树的高度:

当这棵树为空树时,二叉树的高度应该是0,所以当数为空我们返回0,然而当树不等于空时,我们可以以大事化小,小事化了的思想,将当前树的高度转换成左右子树两个中的最大高度再加上一,然后左右子树中最大高度的树的高度又可以转换成我们刚刚的思想,就这样不断递归下去直接我们遇见空节点.

nt BinaryTreeDepth(BTNode* root)
{
	//为空 返回0
	//递归左树 遇到左右都为空的节点 返回1 再递归右树 左右都为空 返回1,
	//左右比较 返回大的+1
	if (root == NULL)
	{
		return NULL;
	}
	NTNode* left = BinaryTreeDepth(root->left);
	NTNode* right = BinaryTreeDepth(root->right);
	return left > right ? left + 1 : right + 1;
}

 查找值为x的节点:

只要找到了就不会返回空,只要返回的不是空就是找到了。左子树找到了就不会再去右子树找

BTNode* BinaryTreeFind(BTNode* root, BTNodeType x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->data == x)
	{
		return root;
	}
	BTNode* left = BinaryTreeFind(root->left);
	if (left != NULL)
	{
		return left;
	}
	BTNode* right = BinaryTreeFind(root->right);
	if (left != NULL)
	{
		return right;
	}
	return NULL;
}

二叉树的层序遍历

借助队列

  1. 先将根入队列
  2. 当前节点出队列后,将次此节点的左右孩子入队列
  3. 一直这样循环往复直到队列为空,说明最后一层已经没有节点了,遍历结束
void BinaryTreeLevelOrder(BTNode* root)
{
	if (root == NULL)
	{
		return NULL;
	}
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		printf("%c", front->data);
		if (front->left != NULL)
		{
			QueuePush(&q, front->left);
		}
		if (front->right != NULL)
		{
			QueuePush(&q, front->right);
		}
	}
	printf("\n");
	QueueDestroy(&q);
}

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

完全二叉树和非完全二叉树的区别:前者一旦有空后面就都是空,而后者一旦有空后面还会出现非空。

第二个while循环是遇到空时候,看后面是否全为空,如果是就是完全二叉树

QueueEmpty(&q)判断队列是否为空,看的是front是否为空

bool BinaryTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front == NULL)
		{
			break;
		}
		else
		{
			QueuePush(&q, front->left);
			QueuePush(&q, front->right);
		}
	}
	//遇到空了
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front)
		{
			QueueDestory(&q);
			return false;
		}
	}
	QueueDestory(&q);
	return true;
}

销毁二叉树:

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

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

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

相关文章

.NET MAUI 发展历程:从 Xamarin 到现代跨平台应用开发框架

文章目录 引言Xamarin 起源&#xff1a;MAUI 的前身Xamarin 的创立&#xff08;2011年&#xff09;Xamarin Studio 与 Visual Studio 集成&#xff08;2013年&#xff09;Xamarin.Forms 的诞生&#xff08;2014年&#xff09;微软收购Xamarin&#xff08;2016年&#xff09; .N…

多模态大语言模型arxiv论文略读(四十)

The Wolf Within: Covert Injection of Malice into MLLM Societies via an MLLM Operative ➡️ 论文标题&#xff1a;The Wolf Within: Covert Injection of Malice into MLLM Societies via an MLLM Operative ➡️ 论文作者&#xff1a;Zhen Tan, Chengshuai Zhao, Raha M…

【蓝桥杯选拔赛真题104】Scratch回文数 第十五届蓝桥杯scratch图形化编程 少儿编程创意编程选拔赛真题解析

目录 scratch回文数 一、题目要求 1、准备工作 2、功能实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 四、程序编写 五、考点分析 六、推荐资料 1、scratch资料 2、python资料 3、C++资料 scratch回文数 第十五届青少年蓝桥杯scratch编…

OpenWrt 与 Docker:打造轻量级容器化应用平台技术分享

文章目录 前言一、OpenWrt 与 Docker 的集成前提1.1 硬件与内核要求1.2 软件依赖 二、Docker 环境部署与验证2.1 基础服务配置2.2 存储驱动适配 三、容器化应用部署实践3.1 资源限制策略3.2 Docker Compose 适配 四、性能优化与监控4.1 容器资源监控4.2 镜像精简策略 五、典型问…

C++初阶----模板初阶

引言 什么是模板 模板是泛型编程的基础&#xff0c;泛型编程是以一种独立于任何特定类型的方式编写代码。 模板也是创建泛型类或者函数的蓝图。 如&#xff1a;库容器&#xff0c;迭代器和算法&#xff0c;都是泛型编程的例子 1. 泛型编程 首先&#xff0c;我们应该了解什么是…

网络流量分析 | 流量分析基础

流量分析是网络安全领域的一个子领域&#xff0c;其主要重点是调查网络数据&#xff0c;以发现问题和异常情况。本文将涵盖网络安全和流量分析的基础知识。 网络安全与网络中的数据 网络安全的两个最关键概念就是&#xff1a;认证&#xff08;Authentication&#xff09;和授…

C语言文件操作完全手册:读写·定位·实战

1.什么是文件 1.1文件的概念 文件&#xff08;File&#xff09;是计算机中用于持久化存储数据的基本单位。它可以存储文本、图片、音频、程序代码等各种信息&#xff0c;并在程序运行结束后仍然保留数据。 1.2文件名 一个文件要有一个唯一的文件标识&#xff0c;以便用户识别…

多模态大语言模型arxiv论文略读(三十七)

A Spectrum Evaluation Benchmark for Medical Multi-Modal Large Language Models ➡️ 论文标题&#xff1a;A Spectrum Evaluation Benchmark for Medical Multi-Modal Large Language Models ➡️ 论文作者&#xff1a;Jie Liu, Wenxuan Wang, Yihang Su, Jingyuan Huan, …

SpringBoot 学习

什么是 SpringBoot SpringBoot 是基于 Spring 生态的开源框架&#xff0c;旨在简化 Spring 应用的初始化搭建和开发配置。它通过约定大于配置的理念&#xff0c;提供快速构建生产级应用的解决方案&#xff0c;显著降低开发者对 XML 配置和依赖管理的负担。 特点&#xff1a; …

VuePress 使用教程:从入门到精通

VuePress 使用教程&#xff1a;从入门到精通 VuePress 是一个以 Vue 驱动的静态网站生成器&#xff0c;它为技术文档和技术博客的编写提供了优雅而高效的解决方案。无论你是个人开发者、团队负责人还是开源项目维护者&#xff0c;VuePress 都能帮助你轻松地创建和管理你的文档…

卷积神经网络--手写数字识别

本文我们通过搭建卷积神经网络模型&#xff0c;实现手写数字识别。 pytorch中提供了手写数字的数据集 &#xff0c;我们可以直接从pytorch中下载 MNIST中包含70000张手写数字图像&#xff1a;60000张用于训练&#xff0c;10000张用于测试 图像是灰度的&#xff0c;28x28像素 …

SQL Server 2019 安装与配置详细教程

一、写在最前的心里话 和 MySQL 对比&#xff0c;SQL Server 的安装和使用确实要处理很多细节&#xff1a; 需要选择配置项很多有“定义实例”的概念&#xff0c;同一机器可以运行多个数据库服务设置身份验证方式时&#xff0c;需要同时配置 Windows 和 SQL 登录要想 Spring …

MyBatisPlus文档

一、MyBatis框架回顾 使用springboot整合Mybatis,实现Mybatis框架的搭建 1、创建示例项目 (1)、创建工程 新建工程 创建空工程 创建模块 创建springboot模块 选择SpringBoot版本 (2)、引入依赖 <dependencies><dependency><groupId>org.springframework.…

Memcached 主主复制架构搭建与 Keepalived 高可用实现

实验目的 掌握基于 repcached 的 Memcached 主主复制配置 实现通过 Keepalived 的 VIP 高可用机制 验证数据双向同步及故障自动切换能力 实验环境 角色IP 地址主机名虚拟 IP (VIP)主节点10.1.1.78server-a10.1.1.80备节点10.1.1.79server-b10.1.1.80 操作系统: CentOS 7 软…

鸿蒙ArkUI之相对布局容器(RelativeContainer)实战之狼人杀布局,详细介绍相对布局容器的用法,附上代码,以及效果图

在鸿蒙应用开发中&#xff0c;若是遇到布局相对复杂的场景&#xff0c;往往需要嵌套许多层组件&#xff0c;去还原UI图的效果&#xff0c;若是能够掌握相对布局容器的使用&#xff0c;对于复杂的布局场景&#xff0c;可直接减少组件嵌套&#xff0c;且随心所欲完成复杂场景的布…

线程函数库

pthread_create函数 pthread_create 是 POSIX 线程库&#xff08;pthread&#xff09;中的一个函数&#xff0c;用于创建一个新的线程。 头文件 #include <pthread.h> 函数原型 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*s…

[C]基础13.深入理解指针(5)

博客主页&#xff1a;向不悔本篇专栏&#xff1a;[C]您的支持&#xff0c;是我的创作动力。 文章目录 0、总结1、sizeof和strlen的对比1.1 sizeof1.2 strlen1.3 sizeof和strlen的对比 2、数组和指针笔试题解析2.1 一维数组2.2 字符数组2.2.1 代码12.2.2 代码22.2.3 代码32.2.4 …

OpenCV 图形API(60)颜色空间转换-----将图像从 YUV 色彩空间转换为 RGB 色彩空间函数YUV2RGB()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 将图像从 YUV 色彩空间转换为 RGB。 该函数将输入图像从 YUV 色彩空间转换为 RGB。Y、U 和 V 通道值的常规范围是 0 到 255。 输出图像必须是 8…

hbuilderx云打包生成的ipa文件如何上架

使用hbuilderx打包&#xff0c;会遇到一个问题。开发的ios应用&#xff0c;需要上架到app store&#xff0c;因此&#xff0c;就需要APP store的签名证书&#xff0c;并且还需要一个像xcode那样的工具来上架app store。 我们这篇文章说明下&#xff0c;如何在windows电脑&…

Golang | 位运算

位运算比常规运算快&#xff0c;常用于搜索引擎的筛选功能。例如&#xff0c;数字除以二等价于向右移位&#xff0c;位移运算比除法快。