当前位置: 首页 > article >正文

C语言二叉树

树的基本概念:

 度:一个节点含有的子节点的个数叫做这个节点的度。列如A的度就是2

叶子节点:没有子节点的节点,叫叶子。例如:D、G、H、F

父亲节点:有一个及以上的子节点的节点,叫父节点。

子节点:有一个爹,他就是子节点,子节点也能是别人的父节点。父节点也能是别人的子节点。

        就像你的爸爸,就是关于你的父节点,你自己就是关于你爸的子节点,你爸也是关于你爷爷的子节点。

兄弟节点 :同一个爹,的两个及以上的节点叫兄弟节点。G,H就是兄弟节点,因为他们有同一个父节点。

树的度: 一个节点有最多的子节点个数,叫做整个数的度,看谁生的多,最多的就是度

如图,最多就是2,那么书的度就是2.

树的高度:从第一节点,开始为1,去数他的子节点连接起来后,最长的那个就是树高。

如图的书高就是4

祖先:就是一个子节点,爹的爹的爹的爹……。子节点上面的一串都是他的祖先包括他爹,直到开山先祖(也就是没有父节点的那个节点为止) ,A就是开山先祖,A,B,E都是G的祖先

        反之儿的儿的儿的儿的儿,就是子孙,每一个都是开山先祖的子孙。B,E,G都是A的子孙

两种树的表示方法

一、孩子兄弟表示法:在结构体里定义两个指针,一个用来指向子节点,一个用来指向同级节点。

二、双亲表示法:用数组实现,只存父亲节点的下标。

二叉树的基本概念

每个节点的子节点不超过两个的树,叫二叉树

特殊二叉树:

        满二叉树:每一个节点都有两个子节点(叶子除外)。

               节点个数计算:如果知道高度 h ,那么个数就是,2的h次方减1。诀窍在于,2的N次方等于,2的0次方一直加到2的N-1次方,再加一。

                比如:2的4次方等于16,他就等于,1(0次方)+2(1次方)+4(2次方)+8(3次方)+1=16

        完全二叉树:假设树的高度为4,只有第四层的节点不是满的。并且第四层的节点抽象来看从左往右必须是连续的,最左边不能为NULL就完了呗(不一定对)。

二叉树的性质:

        叶子节点个数,等于度为2的节点个数加一。如下图有4个叶子节点D G H F,度为2的节点有3个 A B E,加一刚好相等

        完全二叉树节点问题:

                如果一个完全二叉树的节点是 2n 个,也就是说节点个数是偶数,那么必然会有一个度为1的节点。

递归深度层序遍历

        

         前序: 根,左子树 ,右子树。每来到一个左子树也时是先访问根,再去看这个左子树的左子树

        解析:先访问 A 再访问左子树 B,再访问左子树 D,因为 D 为叶子节点,所以去看 B 的右子树 E,进来访问E后又去访问 G,G 为叶子访问完后,去看 E 的右子树访问E完后,访问H,H为叶子。关键的来了。此时我们B这个左子树就算访问完了,就得去看A的右子树了。

        简化版顺序:A B D E G H C F(有效节点顺序) 

        完整版:A , B , D, NULL , NULL , E , G , NULL , NULL , H , NULL , NULL , (当找到左子树的右叶子时,就可以去找右子树的叶子了) ,C  , NULL , F , NULL , NULL 

最终也是成功通过

创建的测试代码

int main()
{
	BTNode* t1 = (BTNode*)malloc(sizeof(BTNode));
	if (t1 == NULL)
	{
		perror("malloc::fail");
		return EOF;
	}
	t1->data = 'A';
	t1->left = NULL;
	t1->right = NULL;
	BTNode* t2 = (BTNode*)malloc(sizeof(BTNode));
	if (t2 == NULL)
	{
		perror("malloc::fail");
		return EOF;
	}
	t2->data = 'B';
	t2->left = NULL;
	t2->right = NULL;
	BTNode* t3 = (BTNode*)malloc(sizeof(BTNode));
	if (t3 == NULL)
	{
		perror("malloc::fail");
		return EOF;
	}
	t3->data = 'C';
	t3->left = NULL;
	t3->right = NULL;
	BTNode* t4 = (BTNode*)malloc(sizeof(BTNode));
	if (t4 == NULL)
	{
		perror("malloc::fail");
		return EOF;
	}
	t4->data = 'D';
	t4->left = NULL;
	t4->right = NULL;
	BTNode* t5 = (BTNode*)malloc(sizeof(BTNode));
	if (t5 == NULL)
	{
		perror("malloc::fail");
		return EOF;
	}
	t5->data = 'E';
	t5->left = NULL;
	t5->right = NULL;
	BTNode* t6 = (BTNode*)malloc(sizeof(BTNode));
	if (t6 == NULL)
	{
		perror("malloc::fail");
		return EOF;
	}
	t6->data = 'F';
	t6->left = NULL;
	t6->right = NULL;
	BTNode* t7 = (BTNode*)malloc(sizeof(BTNode));
	if (t7 == NULL)
	{
		perror("malloc::fail");
		return EOF;
	}
	t7->data = 'G';
	t7->left = NULL;
	t7->right = NULL;
	BTNode* t8 = (BTNode*)malloc(sizeof(BTNode));
	if (t8 == NULL)
	{
		perror("malloc::fail");
		return EOF;
	}
	t8->data = 'H';
	t8->left = NULL;
	t8->right = NULL;
	t1->left = t2;
	t1->right = t3;
	t2->left = t4;
	t2->right = t5;
	t3->left = NULL;
	t3->right = t6;
	t5->left = t7;
	t5->right = t8;
	PrevOrder(t1);
}

递归解析:(只讲前序),观看顺序就是从左往右看,注意连线和粉红色字体就行。

中序:左子树 ,根 ,右子树

        从D开始访问,完了回到B(根)访问B,再去看右子树,进去之后先访问G再是E,再去看右子树H,访问完后,来到C,左子树为空掠过访问C,再去看右子树,F的两个都是空,访问F。

        简化版顺序:D B G E H A C F

        完整版为:NULL D NULLL B NULL G NULL E NULL H NULL (A的左子树),A NULL C NULL F NULL 。(A的右子树)

    

    后序: 左子树,右子树 ,根

二叉树计算:

        节点计算:我们把二叉树的左右节点叫做左子树和右子树,即使他是一个叶子,也叫左右子树,我们要有左右子树的这种观念,递归下去看的是一棵树,而不只是单纯的一个节点。

int NodeSize(BTNode* root)//求节点个数
{
	if (root == NULL)//判断节点为空嘛?
	{
		return 0;//为空返回0 
	}
	else
	{	//不为空返回1+他的左子树的节点个数,以及右子树节点个数
		return 1 + NodeSize(root->left) + NodeSize(root->right);
	}
}

如果这个节点不为空,则会去看左子树的节点个数,和右子树的节点个数

        叶子节点:

int TreeLeafSize(BTNode* root)//叶子的个数
{
	if (root == NULL)//解决空树
	{
		return 0;
	}
	if (root->left == NULL && root->right == NULL)
	{
		return 1;

	}//看这个节点是不是叶子,是就返回1不是就来到else
	else
	{	//去看他的左右子树的统计个数
		return TreeLeafSize(root->left) + TreeLeafSize(root->right);

	}
		
}

为叶子节点时开始返回,根会记录下左右子树有几个叶子节点。

深度计算:

int maxDepth(BTNode* root)//求树的深度
{
	if (root == NULL)
		return 0;
	else
	{
		int left = maxDepth(root->left);//记录左子树深度
		int right = maxDepth(root->right);//记录右子树的深度

		if (left > right)
		{
			return 1 + left;//如果说左子树的深度大于右子树,返回左子树的深度再+1,
							//+1表示根的这一层
		}
		else
			return 1 + right;//这样就只会得到一边的深度另一边抛弃
							 //就算是度为0的子树也会返回1;
	}
}

深度为:1(代表根这一层)+左右子树深度更大的那一个

平衡树判断:

 用深度函数,计算出深度,然后判断

bool isbalance(BTNode* root)
{
	if (root == NULL)
		return true;
	int left = maxDepth(root->left);
	int right = maxDepth(root->right);//左右子树的深度

	if ((left - right < 2) && (left - right > -2))//判断
		return true;
	else
		return false;
	
}


http://www.kler.cn/a/373470.html

相关文章:

  • 【数字化】华为-用变革的方法确保规划落地
  • Vue2+OpenLayers给标点Feature添加信息窗体(提供Gitee源码)
  • Oracle EBS GL定期盘存WIP日记账无法过账数据修复
  • 【Hive】新增字段(column)后,旧分区无法更新数据问题
  • MYSQL5.7 全文检索中文无返回数据
  • 深度学习中的学习率调度器(scheduler)分析并作图查看各方法差异
  • 破解OCR生僻字难题,中安文字识别技术让文字录入更简单
  • Javascript——KMP算法
  • C#实现MD5加密
  • 有没有优质的公司可以提供高质量大模型数据?
  • laravel 安装后台管理系统, filament.
  • 学习区模型分享
  • float(‘inf‘)中inf是什么意思
  • linux之网络子系统- 内核接收数据包以及相关实际问题
  • 基于Gin和GORM的在线判题系统后端
  • 达梦变量赋值
  • 为什么选择AWS
  • Flink CDC系列之:理解学习Kubernetes模式
  • 【制造业&PPE】安全帽等施工现场安全防护装备识别图像分割系统源码&数据集全套:改进yolo11-DRBNCSPELAN
  • c++/qt调阿里云视觉智能开发平台
  • logback日志级别动态切换四种方案
  • 什么是x86架构,什么是arm架构
  • 【果蔬识别】Python+卷积神经网络算法+深度学习+人工智能+机器学习+TensorFlow+计算机课设项目+算法模型
  • 【Redis】
  • 设计模式 - 工厂方法模式
  • 前端部署指南:手把手教你部署 Vue 项目