【数据结构初阶】--二叉树(五)

发布于:2025-08-13 ⋅ 阅读:(14) ⋅ 点赞:(0)

😘个人主页@Cx330❀

👀个人简介一个正在努力奋斗逆天改命的二本觉悟生

📖个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》

前言:通过上篇博客的学习,我们实现了二叉树的前中后序遍历,体验到了递归的暴力美学,这篇博客将带着大家实现二叉树的接口


目录

一、求二叉树节点个数

代码实现:

test.c:

测试结果:

二.求二叉树叶子节点个数

代码实现:

test.c:

测试结果:

三.求二叉树第k层节点个数

代码实现:

test.c:

测试结果:

 四.求二叉树的深度/高度

代码实现:

test.c:

测试结果:

五.二叉树查找值为x的节点

代码实现:

test.c:

测试结果:

六.二叉树的销毁 

七、代码展现

Tree.h:

Tree.c:

test.c:


一、求二叉树节点个数

在正式开始之前我们先把上次写的代码里的test.c中创建树的代码优化一下,这样方便后续操作

#include"Tree.h"
 
BTNode* buyNode(char x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	newnode->data = x;
	newnode->left = newnode->right = NULL;
	return newnode;
}
BTNode* CreateTree()
{
	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 test1()
{
	BTNode* root = CreateTree();
 
	//前中后序遍历
	//PreOrder(root);
	//InOrder(root);
	//PostOrder(root);
}
 
int main()
{
	test1();
	return 0;
}

二叉树节点个数=根节点+左子树节点个数+右子树节点个数

代码实现:

//方法三:节点总数=1+左子树节点个数+右子树节点个数
int BinaryTreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}

如图:

test.c:

#include"Tree.h"
 
BTNode* buyNode(char x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	newnode->data = x;
	newnode->left = newnode->right = NULL;
	return newnode;
}
BTNode* CreateTree()
{
	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 test1()
{
	BTNode* root = CreateTree();
 
	//前中后序遍历
	//PreOrder(root);
	//InOrder(root);
	//PostOrder(root);
 
	//二叉树结点个数
	printf("Size: %d\n", BinaryTreeSize(root));
}
 
int main()
{
	test1();
	return 0;
}

测试结果:

测试结果正确,程序退出码为0


二.求二叉树叶子节点个数

叶子节点:左右孩子都为空的节点

二叉树叶子节点个数=左子树叶子节点个数+右子树叶子节点个数

代码实现:

// ⼆叉树叶⼦结点个数
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);
}

如图:

test.c:

#include"Tree.h"
 
BTNode* buyNode(char x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	newnode->data = x;
	newnode->left = newnode->right = NULL;
	return newnode;
}
BTNode* CreateTree()
{
	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 test1()
{
	BTNode* root = CreateTree();
 
	//前中后序遍历
	//PreOrder(root);
	//InOrder(root);
	//PostOrder(root);
 
	//二叉树结点个数
	//printf("Size: %d\n", BinaryTreeSize(root));
	//二叉树叶子结点个数
	printf("LeafSize: %d\n", BinaryTreeLeafSize(root));
}
 
int main()
{
	test1();
	return 0;
}

测试结果:

测试结果正确,程序退出码为0


三.求二叉树第k层节点个数

当k==1时当前节点就是第k层节点

二叉树第k层节点个数=左子树第k-1层节点个数+右子树第k-1层节点个数

代码实现:

// ⼆叉树第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);
}

如图:

test.c:

#include"Tree.h"
 
BTNode* buyNode(char x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	newnode->data = x;
	newnode->left = newnode->right = NULL;
	return newnode;
}
BTNode* CreateTree()
{
	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 test1()
{
	BTNode* root = CreateTree();
 
	//前中后序遍历
	//PreOrder(root);
	//InOrder(root);
	//PostOrder(root);
 
	//二叉树结点个数
	//printf("Size: %d\n", BinaryTreeSize(root));
	//二叉树叶子结点个数
	//printf("LeafSize: %d\n", BinaryTreeLeafSize(root));
	//第k层节点个数
	printf("K Size: %d\n", BinaryTreeLevelKSize(root,3));
}
 
int main()
{
	test1();
	return 0;
}

测试结果:

测试结果正确,程序退出码为0


 四.求二叉树的深度/高度

二叉树的高度=根节点+max(左子树的高度,右子树的高度)

代码实现:

//⼆叉树的深度/⾼度
int BinaryTreeDepth(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	//根节点+MAX(左子树高度,右子树高度)
	int leftDep = BinaryTreeDepth(root->left);
	int rightDep = BinaryTreeDepth(root->right);
	return 1 + (leftDep > rightDep ? leftDep : rightDep);
}

如图:

test.c:

#include"Tree.h"
 
BTNode* buyNode(char x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	newnode->data = x;
	newnode->left = newnode->right = NULL;
	return newnode;
}
BTNode* CreateTree()
{
	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 test1()
{
	BTNode* root = CreateTree();
 
	//前中后序遍历
	//PreOrder(root);
	//InOrder(root);
	//PostOrder(root);
 
	//二叉树结点个数
	//printf("Size: %d\n", BinaryTreeSize(root));
	//二叉树叶子结点个数
	//printf("LeafSize: %d\n", BinaryTreeLeafSize(root));
	//第k层节点个数
	//printf("K Size: %d\n", BinaryTreeLevelKSize(root,3));
	//二叉树的深度/高度
	printf("Depth: %d\n", BinaryTreeDepth(root));
}
 
int main()
{
	test1();
	return 0;
}

测试结果:

测试结果正确,程序退出码为0


五.二叉树查找值为x的节点

递归查找,找到了就返回当前节点,如果是在左子树中找到就直接返回,没找到继续来到右子树找,最好都没找到就返回NULL

代码实现:

// ⼆叉树查找值为x的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->data == x)
	{
		return root;
	}
	BTNode* leftFind = BinaryTreeFind(root->left,x);
	if (leftFind)
	{
		return leftFind;
	}
	BTNode* rightFind = BinaryTreeFind(root->right, x);
	if (rightFind)
	{
		return rightFind;
	}
	return NULL;
}

如图:

test.c:

#include"Tree.h"
 
BTNode* buyNode(char x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	newnode->data = x;
	newnode->left = newnode->right = NULL;
	return newnode;
}
BTNode* CreateTree()
{
	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 test1()
{
	BTNode* root = CreateTree();
 
	//前中后序遍历
	//PreOrder(root);
	//InOrder(root);
	//PostOrder(root);
 
	//二叉树结点个数
	//printf("Size: %d\n", BinaryTreeSize(root));
	//二叉树叶子结点个数
	//printf("LeafSize: %d\n", BinaryTreeLeafSize(root));
	//第k层节点个数
	//printf("K Size: %d\n", BinaryTreeLevelKSize(root,3));
	//二叉树的深度/高度
	//printf("Depth: %d\n", BinaryTreeDepth(root));
	//二叉树查找值为x的结点
	BTNode* pos = BinaryTreeFind(root, 'E');
	if (pos)
	{
		printf("找到了\n");
	}
	else {
		printf("没找到\n");
	}
}
 
int main()
{
	test1();
	return 0;
}

测试结果:

测试结果正确,程序退出码为0


六.二叉树的销毁 

--由于提前释放根节点会导致找不到左右子树,所以销毁操作我们要模仿后序遍历,还有这里得传地址,后续的使用也需要注意一下写法。

// ⼆叉树销毁
void BinaryTreeDestory(BTNode** root)
{
	if (*root == NULL)
	{
		return;
	}
	BinaryTreeDestory(&(*root)->left);
	BinaryTreeDestory(&(*root)->right);
	free(*root);
	*root = NULL;
}

如图:


七、代码展现

Tree.h:

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
 
typedef char BTDataType;
typedef struct BinaryNode
{
	BTDataType data;
	struct BinaryNode* left;//左孩子
	struct BinaryNode* right;//右孩子
}BTNode;
 
//前序遍历
void PreOrder(BTNode* root);
 
//中序遍历
void InOrder(BTNode* root);
 
//后序遍历
void PostOrder(BTNode* root);
 
// 二叉树结点个数
int BinaryTreeSize(BTNode* root);
 
// 二叉树叶子结点个数
int BinaryTreeLeafSize(BTNode* root);
 
// 二叉树第k层结点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
 
//二叉树的深度/高度
int BinaryTreeDepth(BTNode* root);
 
// 二叉树查找值为x的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
 
// 二叉树销毁
void BinaryTreeDestory(BTNode** root);

Tree.c:

#include"Tree.h"
 
//前序遍历
void PreOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	//根左右
	printf("%c ", root->data);
	PreOrder(root->left);
	PreOrder(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 BinaryTreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}
 
// 二叉树叶子结点个数=左子树叶子节点个数+右子树节点个数
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-1层节点个数+右子树第k-1层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}
	//判断是否为第k层
	if (k == 1)
	{
		return 1;
	}
	//每次注意要k-1
	return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}
 
//二叉树的深度/高度=根节点+max(左子树高度,右子树高度)
int BinaryTreeDepth(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
 
	int leftdepth = BinaryTreeDepth(root->left);
	int rightdepth = BinaryTreeDepth(root->right);
	return 1 + (leftdepth > rightdepth ? leftdepth : rightdepth);
}
 
// 二叉树查找值为x的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->data == x)
	{
		return root;
	}
 
	BTNode*leftroot = BinaryTreeFind(root->left, x);
	//如果leftroot不为空就是找到了直接返回
	if (leftroot)
	{
		return leftroot;
	}
	//没找到就继续右子树找
	BTNode* rightroot = BinaryTreeFind(root->right, x);
	if (rightroot)
	{
		return rightroot;
	}
	//都没找到就返回空
	return NULL;
}
 
// 二叉树销毁--采用后序遍历的思想
void BinaryTreeDestory(BTNode** root)
{
	if (*root == NULL)
	{
		return;
	}
 
	BinaryTreeDestory(&(*root)->left);
	BinaryTreeDestory(&(*root)->right);
	free(*root);
		*root = NULL;
}

test.c:

#include"Tree.h"
 
BTNode* buyNode(char x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	newnode->data = x;
	newnode->left = newnode->right = NULL;
	return newnode;
}
BTNode* CreateTree()
{
	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 test1()
{
	BTNode* root = CreateTree();
 
	//前中后序遍历
	//PreOrder(root);
	//InOrder(root);
	//PostOrder(root);
 
	//二叉树结点个数
	printf("Size: %d\n", BinaryTreeSize(root));
	//二叉树叶子结点个数
	printf("LeafSize: %d\n", BinaryTreeLeafSize(root));
	//第k层节点个数
	printf("K Size: %d\n", BinaryTreeLevelKSize(root,3));
	//二叉树的深度/高度
	printf("Depth: %d\n", BinaryTreeDepth(root));
	//二叉树查找值为x的结点
	BTNode* pos = BinaryTreeFind(root, 'E');
	if (pos)
	{
		printf("找到了\n");
	}
	else {
		printf("没找到\n");
	}
	// 二叉树销毁
	BinaryTreeDestory(&root);
}
 
int main()
{
	test1();
	return 0;
}

往期回顾:

【数据结构初阶】--树与二叉树预备篇

【数据结构初阶】--二叉树(二)

【数据结构初阶】--二叉树(三)

【数据结构初阶】--二叉树(四)

总结:这篇博客就把二叉树的部分接口实现了,后续还有i一个层序遍历和判断是否为完全二叉树,将在下篇博客给大家展现,如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。


网站公告

今日签到

点亮在社区的每一天
去签到