二叉树的各类功能与函数

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 函数声明
  • 函数实现

前言

提示:这里可以添加本文要记录的大概内容:

今天将最近所学的关于二叉树的所有知识写出博客,比如:深度遍历,层序,计算结点个数等各种的函数实现(c语言),希望能帮助大家。


函数声明:(依次按顺序写函数实现)

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


//树的实现
typedef char BTDataType;

//结点的结构
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

#include "queue.h"

//通过前序遍历将数组"ABD##E#H##CF##G##"构建成二叉树,其中#代表空结点
BTNode* BinaryTreeCreate(BTDataType* a, int* sub);

void BinaryTreeDestory(BTNode* root);//销毁二叉树

int BinaryTreeSize(BTNode* root);//计算二叉树节点个数

//查找值为 a 的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType a);

//计算二叉树叶子节点的个数
int BinaryTreeLeafSize(BTNode* root);

//计算二叉树第k曾的结点个数
int BinaryTreeLevelKSize(BTNode* root, int k);

void BinaryTreePrevOrder(BTNode* root);//前序遍历

void BinaryTreeInOrder(BTNode* root);//中序遍历

void BinaryTreePostOrder(BTNode* root);//后序遍历

void BinaryTreeLevelOrder(BTNode* root);//层序遍历

bool BinaryTreeComplete(BTNode* root);//判断二叉树是否是完全二叉树

BTNode* BinaryTreeCreate(BTDataType* a, int* sub);

//通过前序遍历将数组"ABD##E#H##CF##G##"构建成二叉树,其中#代表空结点

//牛客网上有这个题目

//通过前序遍历将数组"ABD##E#H##CF##G##"构建成二叉树,其中#代表空结点
//a 为字符数组,包含上面这串字符, sub记录数组下标,从0开始
BTNode* BinaryTreeCreate(BTDataType* a, int* sub)
{
	//如果为#则直接返回空结点,并且让下标位置加 1
	if (a[*sub] == '#')
	{
		(*sub)++;
		return NULL;
	}

	//不为空则创造结点,并初始化值,让下标位置加 1
	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	root->data = a[(*sub)++];

	//同理,构建左儿子和右儿子
	root->left = BinaryTreeCreate(a, sub);
	root->right = BinaryTreeCreate(a, sub);

	return root;
}

void BinaryTreeDestory(BTNode* root)//销毁二叉树 

void BinaryTreeDestory(BTNode* root)//销毁二叉树
{
	//运用递归的思想,在最后碰到空结点是结束当前函数
	if (root == NULL)
		return;

	//使用后序遍历销毁二叉树,前,中,后在下面有专门的函数
	BinaryTreeDestory(root->left);
	BinaryTreeDestory(root->right);
	free(root);
}

int BinaryTreeSize(BTNode* root)//计算二叉树节点个数

//力扣上有原题

int BinaryTreeSize(BTNode* root)//计算二叉树节点个数
{
	/*运用分治的思想,将一课树非为根,左子树,右子树
	分好的左子树又可以分为根,左子树,右子树,知道碰到空*/
	if (root == NULL)
		return 0;

	//不为空时则 +1 将当前结点带入计算
	return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

 //查找值为 a 的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType a)

//查找值为 a 的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType a)
{
	if (root == NULL)
		return NULL;
	
	//找到就返回找到的结点
	if (root->data == a)
		return root;

	//对返回的值进行检查,没找到的话就是返回的空,非空就继续返回上一层,直到结束
	BTNode* leftret = BinaryTreeFind(root ->left, a);
	BTNode* rightret = BinaryTreeFind(root ->right, a);
	if(leftret != NULL)
		return leftret;
	if (rightret != NULL)
		return rightret;

	return NULL;
}


 //计算二叉树叶子节点的个数
int BinaryTreeLeafSize(BTNode* root)

//计算二叉树叶子节点的个数
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曾的结点个数
int BinaryTreeLevelKSize(BTNode* root, int k) 

//计算二叉树第k曾的结点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	//在每次递归时,对k进行 -1,这样在k == 1时就到达了第k层
	//从而计算k层的节点个数,与普通的计算结点个数类似(深度从1开始)

	//检查k
	assert(k > 0);
	
	if (root == NULL)
	{
		return 0;
	}

	if (k == 1)
		return 1;

	return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}

前,中,后序 

//只是改变了访问根节点的顺序,三个函数都类似

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


void BinaryTreeInOrder(BTNode* root)//中序遍历
{
	if (root == NULL)
		return;

	BinaryTreePrevOrder(root->left);
	printf("%c ", root->data);
	BinaryTreePrevOrder(root->right);
	return;
}

void BinaryTreePostOrder(BTNode* root)//后序遍历
{
	if (root == NULL)
		return;

	BinaryTreePrevOrder(root->left);
	BinaryTreePrevOrder(root->right);
	printf("%c ", root->data);
	return;
}

void BinaryTreeLevelOrder(BTNode* root)//层序遍历 

//这里要用到队列,可以自己手写,也可以用c++自带的,这里本人用的是自己写的
 

//这是队列的函数声明,并将树的节点重命名
typedef struct BinaryTreeNode* QDataType;

typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;

typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Que;

void QInit(Que* pa);//初始化队列

void QDestory(Que* pa);//销毁队列

bool QueueEmpty(Que* pa);//判断队列是否为空

void QueuePush(Que* pa, QDataType x);//添加数据

void QueuePop(Que* pa);//删除数据

QDataType QueueFront(Que* pa);//取队头的数据

QDataType QueueBack(Que* pa);//取队尾数据
void BinaryTreeLevelOrder(BTNode* root)//层序遍历
{
	assert(root);
	//创建队列
	Que q1;
	QInit(&q1);
	QueuePush(&q1, root);
	while (!QueueEmpty(&q1))
	{
		QDataType tem = QueueFront(&q1);
		QueuePop(&q1);		
		printf("%c ", tem->data);
		if(tem ->left)
		QueuePush(&q1, tem->left);
		if(tem->right)
		QueuePush(&q1, tem->right);
	}
	printf("\n");
	QDestory(&q1);
}

bool BinaryTreeComplete(BTNode* root)

//判断二叉树是否是完全二叉树 

bool BinaryTreeComplete(BTNode* root)//判断二叉树是否是完全二叉树
{
	assert(root);
	//创建队列
	Que q1;
	QInit(&q1);
	QueuePush(&q1, root);
	while (!QueueEmpty(&q1))
	{
		QDataType tem = QueueFront(&q1);
		QueuePop(&q1);
		if (tem == NULL)
		{
			break;
		}
		QueuePush(&q1, tem->left);
		QueuePush(&q1, tem->right);
	}

	while (!QueueEmpty(&q1))
	{
		QDataType tem = QueueFront(&q1);
		QueuePop(&q1);
		if (tem != NULL)
		{
			QDestory(&q1);
			return false;
		}
	}	
	QDestory(&q1);
	return true;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值