【C++课程学习】:二叉树的基本函数实现

🎁个人主页:我们的五年

🔍系列专栏:C++课程学习

🎉欢迎大家点赞👍评论📝收藏⭐文章

目录

🍉二叉树的结构类型:

🍉1.创建二叉树函数(根据数组,前序遍历创建二叉树):

🍉2.销毁二叉树函数:

🍉3.前序遍历函数:

🍉4.二叉树的节点个数函数:

🍉5.计算二叉树叶子节点的个数函数:

🍉6.计算第k层的节点个数:

🍉7.查找节点为k的元素,返回这个元素的指针

🍉8.层序遍历,借助队列:

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


前言:

学了那么久的二叉树,现在基本的二叉树学的差不多了,现在就给大家带来二叉树的几个基本函数。函数有几个,但是基本都不难,基本就是用了分治,递归的思想,画递归展开图也是一种很好理解递归过程好方法,等熟悉以后,就对递归有了更深的理解,面对有一些问题就直接可以写出来。

🍉二叉树的结构类型:

//二叉树的节点结构类型
typedef struct BinaryTreeNode {
BTDataType data;
struct BinaryTreeNode* left; //左孩子节点的地址
struct BinaryTreeNode* right; //右孩子的地址
}BTNode;

每个父节点都包:

1.含存储的数据。

2.左孩子地址。

3.右孩子节点的地址。

🍉1.创建二叉树函数(根据数组,前序遍历创建二叉树):

画递归展开图也是很好理解的,先创建父亲节点,然后往左走,遇到'#',就返回NULL,返回上一层。

复制代码
//根据数组创建二叉树,下面举例的是字符数组,创建的顺序是前序遍历
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{
	if (a[*pi] == '#')
	{
		(*pi)++;
		return NULL;
	}
	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	root->data = a[*pi];	//前序遍历,先创建中间根节点
	(*pi)++;
	root->left = BinaryTreeCreate(a,pi);	//左子树
	root->right = BinaryTreeCreate(a,pi);	//右子树
	return root;	//返回root节点
}

🍉2.销毁二叉树函数:

销毁二叉树也可以前序遍历删除,也可以中序删除。不过如果是前序删除,就要在先保存左右孩子的节点。如果是中序删除,就是要保存右节点。

只有后序遍历删除不要保存节点。

复制代码
// 二叉树销毁
void BTDestory(BTNode** root)
{
	if (*root == NULL)
		return;
    //后序遍历销毁二叉树
	BTDestory(&(*root)->left);
	BTDestory(&(*root)->right);
	free(*root);
	*root = NULL;
}

🍉3.前序遍历函数:

前序遍历和中序遍历和后序遍历基本差不多,只有后面的两个函数和打印的顺序不一样。

复制代码
//前序遍历
void BTPreOreder(BTNode* root)
{
	if (root == NULL)
	{
		printf("# ");
		return;
	}
	printf("%c ",root->data);
	BTPreOreder(root->left);
	BTPreOreder(root->right);
}

🍉4.二叉树的节点个数函数:

分治思想也是yyds

复制代码
// 二叉树节点个数
int BTSize(BTNode* root)
{
	if (root == NULL)
		return 0;
    //个数等于左树节点个数+右树节点个数+1
	return BTSize(root->left)+BTSize(root->right)+1;
}

🍉5.计算二叉树叶子节点的个数函数:

分治

复制代码
// 二叉树叶子节点个数
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);
}

🍉6.计算第k层的节点个数:

要注意的是,遇到NULL,要返回,还有就是,k==1,return 1,要在后面,因为如果在前面,k确实等于1。但是这时候是空节点,所以不能return 1,所以return 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);
}

🍉7.查找节点为k的元素,返回这个元素的指针

找父节点,父节点不是,就去左树,左树没有,就去右树。

只要找到了就返回,所以是或的关系;

复制代码
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
		return NULL;
	if (root->data == x)
		return root;
	BTNode* p1 = BinaryTreeFind(root->left, x);
	if (p1!=NULL)
		return p1;
	BTNode* p2 = BinaryTreeFind(root->right, x);
	if (p2!=NULL)
		return p2;
	return NULL;
}

🍉8.层序遍历,借助队列:

先在队列中插入root,在队列头出一个数据,就入这个节点的左右孩子节点。因为队列有先进先出的特点,所以能达到层序的目的。

复制代码
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{
	Queue ps;
	QueueInit(&ps);
	QueuePush(&ps, root);
	while (!QueueEmpty(&ps))
	{
		BTNode* node = QueueTop(&ps);
		if (node == NULL)
		{
			break;
		}
		else
		{
			printf("%c ", node->data);		
			QueuePush(&ps, node->left);
			QueuePush(&ps, node->right);
		}
		QueuePop(&ps);
	}
	QueueDestroy(&ps);
}

🍉9.判断是否为完全二叉树:

先入数据,然后出,和层序遍历一样,当需要NULL就结束。然后看后面的队列是否都是NULL,如果只要有一个不是NULL,那肯定就不是完全二叉树了,前面都有NULL,后面又出现节点。

复制代码
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root)
{
	Queue ps;
	QueueInit(&ps);
	QueuePush(&ps, root);
	while (!QueueEmpty(&ps))
	{
		BTNode* node = QueueTop(&ps);
		if (node == NULL)
		{
			break;
		}
		else
		{
			QueuePush(&ps, node->left);
			QueuePush(&ps, node->right);
		}
		QueuePop(&ps);
	}
	while (!QueueEmpty(&ps))
	{
		BTNode* node = QueueTop(&ps);
		if (node != NULL)
			return 0;
		QueuePop(&ps);
	}
	return 1;
}
相关推荐
YJlio1 分钟前
第9章小结(9.19):Sysinternals 安全工具组合拳与脚本清单
java·学习·平面
xian_wwq6 分钟前
【学习笔记】网络安全死于平庸
笔记·学习·安全防护
程序员-King.11 分钟前
day110—同向双指针(数组)—最多K个重复元素的最长子数组(LeetCode-2958)
算法·leetcode·双指针
傻小胖12 分钟前
第3讲:BTC-数据结构-北大肖臻老师客堂笔记
数据结构
做怪小疯子18 分钟前
LeetCode 热题 100——二叉树——二叉树的右视图
算法·leetcode·职场和发展
Swift社区21 分钟前
LeetCode 442 - 数组中重复的数据
算法·leetcode·职场和发展
努力学算法的蒟蒻24 分钟前
day25(12.5)——leetcode面试经典150
算法·leetcode·职场和发展
xlq2232226 分钟前
23.二叉树搜索树(下)
数据结构·c++·算法
d111111111d26 分钟前
在STM32F103C8T6中什么是读写寄存器模型,有什么用,可以干什么,详细解释。
笔记·stm32·单片机·嵌入式硬件·学习
金士顿26 分钟前
DI滤波学习
学习