二叉树递归代码及图解(c语言):(前序,中序,后续,节点与叶子个数)

前言

重点图解二叉树的前序,中序,后序,树节点个数,叶子个数及树的高度的递归过程,用图解把各功能的递归过程展开进行分析。

递归介绍

递归,是指在函数的定义中使用函数自身的方法。实际上,递归,顾名思义,其包含了“递”和“归”两个概念。"递"指的是问题规模逐层减小,"归"则表示问题的解决依赖于解决其子问题。在运行过程中,如果一个函数在执行过程中直接或间接调用了自身,这种现象就被称为递归。例如,阶乘函数就是一个典型的递归函数,因为在计算n的阶乘时,我们需要计算(n-1)的阶乘,然后乘以n。递归的思想是把一个大型复杂问题层层转化为一个与原问题规模更小的问题,问题被拆解成子问题后,递归调用继续进行,直到子问题无需进一步递归就可以解决的。

二叉树介绍

  二叉树是一种特殊的数据结构,它是由n个有限元素的集合构成。这个集合或者为空,或者由一个被称为根的元素以及两个不相交的、被称为左子树和右子树的二叉树组成。按照定义,每个节点最多只能有两个子节点,因此我们常说二叉树不存在度大于2的节点。另外,根据二叉树的性质,我们可以知道,如果二叉树的深度为K,那么此二叉树最多有2^K-1个节点。

二叉树特点
  • 每个节点最多只能有两颗子树,且分别称为左子树和右子树。
  • 可以有多种形态,如空二叉树(没有节点),只有根节点的二叉树,只有左子树或只有右子树的二叉树,以及既有左子树又有右子树的二叉树。
  • 具有五种特殊类型的二叉树,包括斜树、满二叉树、完全二叉树等。
  • 第i层上最多有2^(i-1)个节点。
  • 如果二叉树的深度为K,那么此二叉树最多有2^K -1个节点。
  • 对于每一个结点来说都是由其父结点分支表示的,假设树中分枝数为 B,那么总结点数 n=B+1。

完全二叉树:完全二叉树是一种二叉树的特殊形式,除了最后一层外,其它各层的节点数都应达到最大值,并且需要满足最后一层所有节点都连续集中在最左边。同时,完全二叉树也要求最后一层的所有节点都是叶子节点。此外,如果一棵深度为k的有n个结点的二叉树,对其所有结点按从上至下、从左到右的顺序进行编号,若编号为i(1≤i≤n)的结点在满二叉树中的位置与在完全二叉树中的位置相同,则这棵二叉树也可称为完全二叉树。

创建二叉树

创建二叉树的节点
BTNode* CreateNode(BTDataType x)//创建节点
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	node->data = x;
	node->left = NULL;
	node->right = NULL;
	return node;
}
快速构建个二叉树

以下图ABCDE为例(递归案例),快速构建二叉树可以这样

	BTNode* A = CreateNode('A');
	BTNode* B = CreateNode('B');
	BTNode* C = CreateNode('C');
	BTNode* D = CreateNode('D');
	BTNode* E = CreateNode('E');
	A->left = B;
	A->right = C;
	B->left = D;
	B->right = E;

二叉树前序遍历

前序递归代码
void PrevOrder(BTNode* root)//前序遍历
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%C ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);
}
前序递归分解图例

二叉树中序遍历

中序递归代码
void InOrder(BTNode* root)//中序遍历
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	InOrder(root->left);
	printf("%C ", root->data);
	InOrder(root->right);
}
 中序递归分解图例

二叉树后序遍历

后序递归代码
void PostOrder(BTNode* root)//后续遍历
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%C ", root->data);

}
后序递归分解图例

二叉树的节点个数

节点个数的递归代码
int TreeSize(BTNode* root)//树的节点个数
{
	if (root==NULL)
	{
		return 0;
	}

	return 1 + TreeSize(root->left) + TreeSize(root->right);
}
ThreeSize递归分解图例

 二叉树的叶子节点个数

计算叶子节点递归代码

函数ThreeLeafSize();

int ThreeLeafSize(BTNode* root)//树的叶子节点
{
	if (root == NULL)
		return 0;
	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}
	return  ThreeLeafSize(root->left) + ThreeLeafSize(root->right);
}
计算叶子节点的分解图例

 计算树的高度

树高度递归代码

函数maxDepth();

int maxDepth(BTNode* root)//树的高度
{
	if (root == NULL)
		return 0;
	
	int leftDepth = maxDepth(root->left);
	int rightDepth = maxDepth(root->right);
	return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}
 计算树高度的分解图例

注意:return三目操作的返回值

 全部代码

#include<stdio.h>
#include<stdlib.h>

typedef char BTDataType;
typedef struct BinaryTreeNode {
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

void PrevOrder(BTNode* root)//前序遍历
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%C ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);
}

void InOrder(BTNode* root)//中序遍历
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	InOrder(root->left);
	printf("%C ", root->data);
	InOrder(root->right);
}
void PostOrder(BTNode* root)//后续遍历
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%C ", root->data);

}



int TreeSize(BTNode* root)//树的节点个数
{
	if (root==NULL)
	{
		return 0;
	}

	return 1 + TreeSize(root->left) + TreeSize(root->right);
}

//void  TreeSize1(BTNode* root,int*psize)//树的节点个数
//{
//	if (root == NULL)
//	{
//		return 0;
//	}
//	else
//	{
//		(*psize)++;
//	}
//	TreeSize1(root->left,psize);
//	TreeSize1(root->right,psize);
//	
//}


int ThreeLeafSize(BTNode* root)//树的叶子节点
{
	if (root == NULL)
		return 0;
	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}
	return  ThreeLeafSize(root->left) + ThreeLeafSize(root->right);
}

int maxDepth(BTNode* root)//树的高度
{
	if (root == NULL)
		return 0;
	
	int leftDepth = maxDepth(root->left);
	int rightDepth = maxDepth(root->right);
	return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}

BTNode* CreateNode(BTDataType x)//创建节点
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	node->data = x;
	node->left = NULL;
	node->right = NULL;
	return node;
}


int main()
{

	BTNode* A = CreateNode('A');
	BTNode* B = CreateNode('B');
	BTNode* C = CreateNode('C');
	BTNode* D = CreateNode('D');
	BTNode* E = CreateNode('E');

	//快速构建树
	A->left = B;
	A->right = C;
	B->left = D;
	B->right = E;

	printf("前序:");
	PrevOrder(A);//前序
	printf("\n");

	printf("中序:");
	InOrder(A);//中序
	printf("\n");
	printf("后序:");
	PostOrder(A);//后序
	printf("\n");
	printf("\n");


	//int size1 = 0;
	//TreeSize1(A, &size1);
	//printf("TreeSize1=%d", size1);//根为A时二叉树总节点个数

	//int size2 = 0;
	//TreeSize1(B, &size2);
	//printf("TreeSize1=%d", size2);//根为B时二叉树总节点个数
	


	printf("TreeSizeA=%d\n", TreeSize(A));//根为A时二叉树节点个数
	printf("TreeSizeB=%d\n", TreeSize(B));//根为B时二叉树节点个数
    
	printf("ThreeLeafSizeA=%d\n", ThreeLeafSize(A));//根为A时叶子节点个数
	printf("ThreeLeafSizeB=%d\n", ThreeLeafSize(B));//根为B时叶子节点个数
	
	printf("maxDepthA=%d\n", maxDepth(A));//根为A时树的高度为
	printf("maxDepthB=%d\n", maxDepth(B));//根为B时树的高度为


	return 0;
}
 运行结果

  以上就是本期内容,欢迎参考指正,如有不懂,欢迎评论或私信出下期!!!

  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
二叉树的创建可以通过动态内存分配来实现,具体步骤如下: 1. 定义二叉树结构体,包括据域和左右子树指针。 2. 申请内存空间,将据域和左右子树指针初始化为空。 3. 递归创建左右子树。 以下是C语言二叉树的创建代码示例: ```c #include <stdio.h> #include <stdlib.h> typedef struct TreeNode { int data; struct TreeNode *left; struct TreeNode *right; } TreeNode; TreeNode* createTree() { int val; scanf("%d", &val); if (val == -1) { // -1表示空节点 return NULL; } TreeNode *node = (TreeNode*)malloc(sizeof(TreeNode)); node->data = val; node->left = createTree(); node->right = createTree(); return node; } ``` 非递归前序遍历二叉树的方法是使用栈来模拟递归过程,具体步骤如下: 1. 将根节点入栈。 2. 取出栈顶元素,访问该节点。 3. 如果该节点有右子树,将右子树入栈。 4. 如果该节点有左子树,将左子树入栈。 5. 重复步骤2-4,直到栈为空。 以下是C语言二叉树的非递归前序遍历代码示例: ```c void preOrder(TreeNode *root) { if (root == NULL) { return; } TreeNode *stack[100]; int top = -1; stack[++top] = root; while (top >= 0) { TreeNode *node = stack[top--]; printf("%d ", node->data); if (node->right != NULL) { stack[++top] = node->right; } if (node->left != NULL) { stack[++top] = node->left; } } } ``` 非递归中序遍历二叉树的方法也是使用栈来模拟递归过程,具体步骤如下: 1. 将根节点入栈。 2. 如果当前节点有左子树,将左子树入栈。 3. 如果当前节点没有左子树,取出栈顶元素,访问该节点,如果该节点有右子树,将右子树入栈。 4. 重复步骤2-3,直到栈为空。 以下是C语言二叉树的非递归中序遍历代码示例: ```c void inOrder(TreeNode *root) { if (root == NULL) { return; } TreeNode *stack[100]; int top = -1; TreeNode *node = root; while (node != NULL || top >= 0) { while (node != NULL) { stack[++top] = node; node = node->left; } node = stack[top--]; printf("%d ", node->data); node = node->right; } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锻炼²

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值