二叉树的基本操作

news2024/11/18 14:33:55

目录

一、二叉树遍历

       1、前序遍历:                 

动态图解析:

       2、中序遍历:

       3、后序遍历:

       4、层序遍历 (利用队列)

动态图解析:

二、统计二叉树的节点个数:

       1、二叉树总节点个数

       2、二叉树叶子节点个数

       3、二叉树第K层节点个数

三、查找二叉树中值为x的节点

四、代码总览:


一、二叉树遍历

      注: 由于二叉树结构的特殊性,我们采用递归的方式进行遍历。

       1、前序遍历:                 

         根节点 --> 左孩子节点 --> 右孩子节点

          一棵最基本的二叉树由一个根和左右两个孩子组成,而前序遍历的意思是:

          先遍历根节点,再遍历左孩子节点,再遍历右孩子节点 ,

          而且二叉树上的所有子树都要符合这种遍历的顺序 。

动态图解析:

//前序遍历:根左右
binary_node* Preorder(binary_node* root)
{
	if (root == NULL)
	{
		printf("# ");
		return NULL;
	}
	printf("%d", root->data);
	Preorder(root->leftNode);	
	Preorder(root->rightNode);
}

       2、中序遍历:

          左孩子节点--> 根节点 --> 右孩子节点

          先遍历根左孩子节点,再遍历根节点,再遍历右孩子节点 ,

          而且二叉树上的所有子树都要符合这种遍历的顺序 。

//中序遍历
binary_node* Inorder(binary_node* root)
{
	if (!root)
		return;
	Inorder(root->leftNode);
	printf("%d ", root->data);
	Inorder(root->rightNode);
}

       3、后序遍历:

          左孩子节点--> 右孩子节点 --> 根节点

          先遍历左孩子节点,再遍历右孩子节点,再遍历根节点 

//后序遍历
binary_node* postorder(binary_node* root)
{
	if (!root)
		return;
	postorder(root->leftNode);
	postorder(root->rightNode);
	printf("%d ", root->data);
}

       4、层序遍历 (利用队列)

               从上到下 ;从左到右 依次遍历

将根节点入队列 >> 遍历根节点(根节点出队列)>> 根节点的孩子节点依次入队列  (以此类推)

动态图解析:

//层序遍历
void sequence(binary_node* root)
{
	if (!root)
		return;
  //创建队列
    binary_node** simuqueue = (binary_node**)malloc(sizeof(binary_node*));  
	int basei = 0;
	simuqueue[basei] = root;                      //根节点入队列
	for (int exporti = 0; exporti<=basei;)
	{
		root = simuqueue[exporti];                //根节点出队列
		printf("%d ", (simuqueue[exporti++])->data);
		if (root->leftNode || root->rightNode)
  //队列扩容		
        simuqueue = realloc(simuqueue, sizeof(binary_node*)*(basei+3));  
		if((root->leftNode))               
		simuqueue[++basei] = root->leftNode;       //左孩子节点入队列
		if((root->rightNode))
		simuqueue[++basei] = root->rightNode;      //右孩子节点入队列
	}
	
}

                         

二、统计二叉树的节点个数:

       1、二叉树总节点个数

            方法一:定义一个全局变量用来计数,每次遍历,该变量++

            方法二:累加 函数返回值的方式 ,每遍历一个节点,返回值++

//统计二叉节点个数
int cont = 0, leafcont = 0;
int binary_size(binary_node* root)
{
   //if (!root)                  ______ 方法一:(全局变量)
		return;
   //cont++;
   //binary_size(root->leftNode);
   //binary_size(root->rightNode);

   //                            —————— 方法二:(函数返回值)
	if (!root)                   
		return 0;
	else
		return 1 + binary_size(root->leftNode) + binary_size(root->rightNode);
}

       2、二叉树叶子节点个数

            判定条件:没有左右孩子节点   ,即为一个叶子节点。(不是叶子节点继续遍历)

//统计叶子节点个数
int binary_leafsize(binary_node* root)
{
	if (!root)
		return 0;
	if ((!root->leftNode)&&(!root->rightNode))    //--如果没有左右孩子
		return 1;                                 //--即为一个叶子节点
	else                                          //不是叶子节点继续遍历
		return  binary_leafsize(root->leftNode)+binary_leafsize( root->rightNode);

}

       3、二叉树第K层节点个数

            利用函数传参,层层递减的方式,确定到第K层,利用返回值累加确定节点个数

(如:初始查找第三层:k = 3,每遍历到下一层,k - - ,当k =1 时, 即遍历到第三层 )

//第k层节点个数
int binary_ksize(binary_node* root,int cont_k)
{
	if (!root)            //第k层没有节点 && 越界(k过大) 《==》 root == NULL
		return 0;
	if (1 == cont_k && root)      //遍历到 k 层并且有节点
		return 1;
	else if (cont_k > 1)          //尚未遍历到 k 层
		return binary_ksize(root->leftNode, cont_k - 1) + binary_ksize(root->rightNode, cont_k - 1);

}

三、查找二叉树中值为x的节点

            依次遍历,比较值即可,(找到返回该节点地址,找不到返回NULL)

            注:要优化遍历次数,如:一条路径找到值后就无需再遍历其他节点了。

//查找二叉树中值为x的节点
binary_node* binary_find(binary_node* root,int x)
{
	if (!root)
		return NULL;
	if (root->data == x)
		return root;
	else
	{   //先遍历左孩子节点
		binary_node* tempL = binary_find(root->leftNode, x);
		if (tempL)
			return tempL;
        //左孩子节点找不到再找右孩子节点
		else if (tempL = binary_find(root->rightNode, x))
		{
			return tempL;
		}
	}
}

四、代码总览:

//前序遍历
binary_node* preorder(binary_node* root)
{
	if (!root)
		return;
	printf("%d ", root->data);
	preorder(root->leftNode);
	preorder(root->rightNode);
}
//中序遍历
binary_node* Inorder(binary_node* root)
{
	if (!root)
		return;
	Inorder(root->leftNode);
	printf("%d ", root->data);
	Inorder(root->rightNode);
}
//后序遍历
binary_node* postorder(binary_node* root)
{
	if (!root)
		return;
	postorder(root->leftNode);
	postorder(root->rightNode);
	printf("%d ", root->data);
}

//统计二叉节点个数
int cont = 0, leafcont = 0;
int binary_size(binary_node* root)
{/*
	if (!root)
		return;
	cont++;
	binary_size(root->leftNode);
	binary_size(root->rightNode);*/

	if (!root)
		return 0;
	else
		return 1 + binary_size(root->leftNode) + binary_size(root->rightNode);
}

//统计叶子节点个数
int binary_leafsize(binary_node* root)
{
	/*if (!root)
		return;
	if ((!root->leftNode) && (!root->rightNode))
		leafcont++;
	binary_leafsize(root->leftNode);
	binary_leafsize(root->rightNode);*/
	if (!root)
		return 0;
	if ((!root->leftNode)&&(!root->rightNode))
		return 1;
	else
		return  binary_leafsize(root->leftNode)+binary_leafsize( root->rightNode);

}

//第k层节点个数
int binary_ksize(binary_node* root,int cont_k)
{
	if (!root)            //第k层没有节点 && 越界 《==》 root == NULL
		return 0;
	if (1 == cont_k && root)      //遍历到 k 层并且有节点
		return 1;
	else if (cont_k > 1)
		return binary_ksize(root->leftNode, cont_k - 1) + binary_ksize(root->rightNode, cont_k - 1);

}

//统计二叉树层数
int binary_layers(binary_node* root)
{
	int layers = 0, temp = 0;
	if (!root)
		return 0;
	return 1+((layers = binary_layers(root->leftNode)) > (temp = binary_layers(root->rightNode)) ? layers : temp);
}

//查找二叉树中值为x的节点
binary_node* binary_find(binary_node* root,int x)
{
	if (!root)
		return NULL;
	if (root->data == x)
		return root;
	else
	{
		binary_node* tempL = binary_find(root->leftNode, x);
		if (tempL)
			return tempL;
		else if (tempL = binary_find(root->rightNode, x))
		{
			return tempL;
		}
	}
}

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

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

相关文章

【OpenAI】基于 Gym-CarRacing 的自动驾驶项目 | 车道检测功能的实现 | 边缘检测与分配 | 样条拟合

限时开放&#xff0c;猛戳订阅&#xff01; &#x1f449; 《一起玩蛇》&#x1f40d; &#x1f4ad; 写在前面&#xff1a; 本篇是关于多伦多大学自动驾驶专业项目的博客。GYM-Box2D CarRacing 是一种在 OpenAI Gym 平台上开发和比较强化学习算法的模拟环境。它是流行的 Box2D…

【High 翻天】Higer-order Networks with Battiston Federico (7)

目录传播与社会动力学&#xff08;1&#xff09;传播simplicial complexeshypergraphs传播与社会动力学&#xff08;1&#xff09; 模拟人类行为的动态过程一直是许多研究的焦点&#xff0c;其中社会关系和交互通常被认为是一种潜在结构&#xff0c;是高阶方法的天然试验场。 …

广告业务系统 之 框架沉淀 —— “数据消费型服务框架”

文章目录广告业务系统 之 框架沉淀 —— “数据消费型服务框架”数据消费型服务统一框架主流程Plugin 构建广告业务系统 之 框架沉淀 —— “数据消费型服务框架” 数据消费型服务统一框架 由于 ADX 系统中&#xff0c;大量数据以流式涌动&#xff0c;整个链路中出现了 “多处…

MMCME4_ADV与PLL4_ADV原语

MMCM与PLL ​ UltraScale器件中时钟管理模块(CMT)包含mixed-mode clock manager (MMCM) 和phase-locked loops (PLLs) 。PLL主要用来生成I/O时钟&#xff0c;也包含一部分MMCM的功能。 ​ 其中MMCM输出时钟相位调整语VCO频率相关。 MMCME4_ADV原语 ​ MMCM原语包含MMCME3_B…

2023年最新版Java入门教程,一套很哇塞的Java基础课

所谓天道好轮回&#xff0c;鬼畜饶过谁。最近B站学习区也沦陷了&#xff0c;由此诞生出了一种让人闻所未闻的冷概念&#xff1a;鬼畜教学法!这种奇怪的组合让人匪夷所思&#xff0c;但架不住网友们的推荐!!!爱嘤嘤嘤斯坦&#xff1a;早看到这些视频&#xff0c;妈妈就再也不用担…

东南亚跨境电商迅猛发展,商机转瞬即逝!

2022年中国跨境电商进入了转型调整期&#xff0c;前几年高歌猛进的发展势头似乎有所减弱。回顾2022年&#xff0c;跨境电商卖家们都表示心情复杂&#xff0c;过去一年&#xff0c;卖家们经历许多大事件&#xff0c;比如9月份拼多多强势推出Temu奔向北美市场&#xff0c;10月份字…

Linux权限和粘滞位

目录 一.权限概念 二.用户分类 三.文件权限 1.执行操作的人的分类 2.文件类型和访问权限&#xff08;事物属性&#xff09; 03.文件权限值的表示方法 四.目录权限与粘滞位 一.权限概念 操作系统用来限制对资源访问的机制&#xff0c;一件事情是否可以被“谁”做&#x…

【观察】浪潮信息龙蜥联合实验室:打造下一代操作系统,筑牢基础软件创新根基...

毫无疑问&#xff0c;在当今世界日益复杂的竞争环境下&#xff0c;随着中国企业数字化转型的加速和自主创新进程的加快&#xff0c;再加上开源和云计算已成为行业发展的大趋势之下&#xff0c;如何在“变局中开新局”&#xff1f;如何解决中国在核心基础软件领域面临的各种挑战…

Java语法七:文件操作---IO

目录 1.File概述 1.1&#xff1a;File概述的方法 2&#xff1a;文件内容的读写 2.1&#xff1a;字节流 2.1.1&#xff1a;读--InputStream 2.1.2&#xff1a;写---OutputStream 2.2&#xff1a;字符 前言&#xff1a; 这一篇我们将讲文件操作的相关方法&#xff0c;以及…

详解Reflect:Reflect和Object的异同,Reflect的一些内置方法以及方法注意点

Reflect Reflect拥有Object对象的一些内部方法&#xff0c;某些方法会同时在Object对象和Reflect对象上部署&#xff0c;也就是说Object对象上存在的方法&#xff0c;通过Reflect也可以访问到。 单论Reflect的话&#xff0c;可以这么理解&#xff0c;Reflect就是继承了Object的…

C语言学习前序 - VS Code安装

要想学习一门编程语言&#xff0c;首先要有一个好的编程工具&#xff0c;推荐大家使用VS Code。 截止到现在&#xff0c;是我最喜欢的代码编辑工具。 工具下载。 官网地址&#xff1a;https://code.visualstudio.com/ 开始下载了&#xff0c;但是很慢很慢。 下载很慢可以直…

【Leetcode面试常见题目题解】4. 盛最多水的容器

题目描述 本文是LC第11题&#xff1a;盛最多水的容器。 题目描述如下&#xff1a; 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多…

.Net 线程安全 (细粒度锁定、无锁机制以及lock)

.Net 线程安全最省事的lock关键字线程安全对象测试环境例子使用Queue源码和结果运行效果使用ConcurrentQueue的源码和结果运行效果volatile关键字易失性内存和非易失性内存的区别易失性内存&#xff1a;非易失性内存&#xff1a;volatile 关键字可应用于以下类型的字段&#xf…

<C++>AVL数

文章目录1. AVL树的概念2. AVL树节点的定义3. AVL树的插入4. AVL树的旋转5. AVL树的验证6. AVL树的性能1. AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0…

MySQL中alter命令知识

MySQL中alter命令知识 文章目录MySQL中alter命令知识(一) 删除、添加、修改字段1、删除表中的字段数据2、添加新字段指定字段插入位置3、修改字段类型和名称&#xff08;二&#xff09;、修改表名&#xff08;三&#xff09;、修改存储引擎创建copy_emp表&#xff0c;便于后面案…

Prompt Learning 简介

最近去参会&#xff0c;看到了大量关于Prompt相关的论文&#xff0c;或者说跟NLP NLU相关的新论文或多或少都使用到了Prompt learning的一些思想或者设置。由于本人主业不是是做NLP的&#xff0c;所以对NLP顶会的这一现象觉得很有意思&#xff0c;趁闲暇学习了一下Prompt learn…

对话 BitSail Contributor | 姚泽宇:新生火焰,未来亦可燎原

2022 年 10 月&#xff0c;字节跳动 BitSail 数据引擎正式开源。同期&#xff0c;社区推出 Contributor 激励计划第一期&#xff0c;目前已有 12 位开发者为 BitSail 社区做出贡献&#xff0c;成为了首批 BitSail Contributor。 江海的广阔是由每一滴水珠构成的&#xff0c;Bi…

【高阶数据结构】手撕哈希表(万字详解)

&#x1f308;欢迎来到数据结构专栏~~手撕哈希表 (꒪ꇴ꒪(꒪ꇴ꒪ )&#x1f423;,我是Scort目前状态&#xff1a;大三非科班啃C中&#x1f30d;博客主页&#xff1a;张小姐的猫~江湖背景快上车&#x1f698;&#xff0c;握好方向盘跟我有一起打天下嘞&#xff01;送给自己的一句…

【jqgrid篇】jqgrid.setCell 改变单元格的值 改变单元格的样式设置单元格属性

setCellrowid,colname, data, class, propertiesjqGrid对象 改变单元格的值。rowid&#xff1a;当前行id&#xff1b;colname&#xff1a;列名称&#xff0c;也可以是列的位置索引&#xff0c;从0开始&#xff1b;data&#xff1a;改变单元格的内容&#xff0c;如果为空则不更 …

将GO、Pathway富集结果整合在一张高颜值圆圈图上

富集分析是生物医学论文中非常常见的一类分析&#xff0c;例如GO富集分析&#xff0c;Pathway富集分析等。其结果一般包括以下几个要素&#xff1a;1&#xff0c;名字&#xff08;GO term或者KEGG description&#xff09;&#xff1b;2&#xff0c;该名字所包含的基因数目&…