二叉树的实现 c语言

注:层序所需的队列文件请参考 C语言 实现栈(顺序表)和队列(链表)-CSDN博客

一、 BTree.h

函数包含:

// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树

// 二叉树销毁

// 二叉树节点个数

// 二叉树叶子节点个数

// 二叉树第k层节点个数

// 二叉树查找值为x的节点

// 二叉树前序遍历

// 二叉树中序遍历

// 二叉树后序遍历

// 层序遍历

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

//求树的高度

函数实现均在BTree.c

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
#include"Queue.h"


typedef char BTDataType;

typedef struct BinaryTreeNode
{
	BTDataType _data;
	struct BinaryTreeNode* _left;
	struct BinaryTreeNode* _right;
}BTNode;

// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a,  int* pi);
// 二叉树销毁
void BinaryTreeDestory(BTNode** root);
// 二叉树节点个数
int BinaryTreeSize(BTNode* root);
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root);
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root);
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root);
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root);
void BinaryTreeLevelOrder1(BTNode* root);
// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root);

二、BTree.c

#include"BTree.h"


BTNode* TreePrevOrderBinaryTreeCreate(BTDataType* a, int* pi)
{
	if ('#' == a[*pi])
	{
		(*pi)++;
		return NULL;
	}
	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	if(NULL == root)
	{
		perror("TreePrevOrderBinaryTreeCreate fail!");
		return NULL;
	}
	root->_data = a[*pi];
	(*pi)++;
	root->_left = TreePrevOrderBinaryTreeCreate(a, pi);
	root->_right = TreePrevOrderBinaryTreeCreate(a, pi);
	return root;
}

// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{
	if (NULL == a)
		return NULL;
	return TreePrevOrderBinaryTreeCreate(a,pi);
}
// 二叉树销毁
void BinaryTreeDestory(BTNode** root)
{
	if (NULL == *root)
		return;
	BinaryTreeDestory(&(*root)->_left);
	BinaryTreeDestory(&(*root)->_right);
	free(*root);
}
// 二叉树节点个数
int BinaryTreeSize(BTNode* root)
{
	if (NULL == root)
		return 0;
	return BinaryTreeSize(root->_left) 
		+ BinaryTreeSize(root->_right) + 1;
}
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{
	if (NULL == root)
		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)
{
	assert(k > 0);
	if(NULL == root)
		return 0;
	if (1 == k)
		return 1;
	return BinaryTreeLevelKSize(root->_left, k-1) +			 BinaryTreeLevelKSize(root->_right, k-1);
	
}
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (NULL == root)
		return NULL;
	if (x == root->_data)
	{
		return root;
	}
	BTNode* ret1 = BinaryTreeFind(root->_left, x);
	BTNode* ret2 = BinaryTreeFind(root->_right, x);
	if (ret1 != NULL)
	{
		return ret1;
	}
	if (ret2 != NULL)
	{
		return ret2;
	}
	return NULL;
}
// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root)
{
	if (NULL == root)
		return;
	printf("%c", root->_data);
	BinaryTreePrevOrder(root->_left);
	BinaryTreePrevOrder(root->_right);
}
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
	if (NULL == root)
		return;
	BinaryTreeInOrder(root->_left);
	printf("%c", root->_data);
	BinaryTreeInOrder(root->_right);
}
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
	if (NULL == root)
		return;
	BinaryTreePostOrder(root->_left);
	BinaryTreePostOrder(root->_right);
	printf("%c", root->_data);
}
// 层序遍历
//需要用到队列,字符
void BinaryTreeLevelOrder(BTNode* root)
{
	if (NULL == root)
		return;
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		printf("%c", q._front->_data->_data);
		if (q._front->_data->_left)
			QueuePush(&q, q._front->_data->_left);
		if (q._front->_data->_right)
			QueuePush(&q, q._front->_data->_right);
		QueuePop(&q);
	}
	printf("\n");
	QueueDestroy(&q);
}

// 层序遍历
//需要用到队列,数字
void BinaryTreeLevelOrder1(BTNode* root)
{
	if (NULL == root)
		return;
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		printf("%d", q._front->_data->_data);
		if (q._front->_data->_left)
			QueuePush(&q, q._front->_data->_left);
		if (q._front->_data->_right)
			QueuePush(&q, q._front->_data->_right);
		QueuePop(&q);
	}
	printf("\n");
	QueueDestroy(&q);
}
 //判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
	if (NULL == root)
		return false;
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		if (NULL == q._front->_data)
		{
			QueuePop(&q);
			break;
		}
		QueuePush(&q, q._front->_data->_left);
		QueuePush(&q, q._front->_data->_right);
		QueuePop(&q);
	}
	while (!QueueEmpty(&q))
	{
		if (NULL != q._front->_data)
		{
			QueueDestroy(&q);
			return false;
		}
		QueuePop(&q);
	}
	QueueDestroy(&q);
	return true;
}
//求树的高度
int TreeSize1(BTNode* root)
{
	if (NULL == root)
	{
		return 0;
	}
	int leftnum = TreeSize1(root->_left);
	int rightnum = TreeSize1(root->_right);
	return leftnum > rightnum ? leftnum + 1 : rightnum + 1;
}

三、BTreeTest.c

#include"BTree.h"

BTNode* BuyNode(BTDataType x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	if (node == NULL)
	{
		perror("malloc fail");
		return NULL;
	}

	node->_data = x;
	node->_left = NULL;
	node->_right = NULL;

	return node;
}

BTNode* CreatBinaryTree()
{
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);
	BTNode* node7 = BuyNode(7);


	node1->_left = node2;
	node1->_right = node4;
	node2->_left = node3;
	node4->_left = node5;
	node4->_right = node6;
	node2->_right = node7;

	return node1;
}

int main()
{
	// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
	int i = 0;
	char a[100] = { "ABD##E#H##CF##G##" };
	BTNode* root = BinaryTreeCreate(a, &i);
	// 二叉树节点个数
	printf("二叉树节点个数:%d\n", BinaryTreeSize(root));
	// 二叉树叶子节点个数
	printf("二叉树叶子节点个数:%d\n", BinaryTreeLeafSize(root));
	// 二叉树第k层节点个数
	int k = 1;
	printf("第%d层节点个数%d\n", k,BinaryTreeLevelKSize(root, k));
	k = 2;
	printf("第%d层节点个数%d\n", k, BinaryTreeLevelKSize(root, k));
	k = 3;
	printf("第%d层节点个数%d\n", k, BinaryTreeLevelKSize(root, k));
	k = 4;
	printf("第%d层节点个数%d\n", k, BinaryTreeLevelKSize(root, k));
	k = 5;
	printf("第%d层节点个数%d\n", k, BinaryTreeLevelKSize(root, k));


	// 二叉树查找值为x的节点
	BTNode* find = BinaryTreeFind(root, 'E');

	// 二叉树前序遍历 
	BinaryTreePrevOrder(root);
	printf("\n");
	// 二叉树中序遍历
	BinaryTreeInOrder(root);
	printf("\n");
	// 二叉树后序遍历
	BinaryTreePostOrder(root);
	printf("\n");


	// 层序遍历
	BinaryTreeLevelOrder(root);
	printf("\n");
	// 判断二叉树是否是完全二叉树,不是
	printf("第一个判断%d", BinaryTreeComplete(root));
	printf("\n");


	BTNode* test = CreatBinaryTree();
	BinaryTreeLevelOrder1(test);
	// 判断二叉树是否是完全二叉树,是
	printf("第二个判断%d", BinaryTreeComplete(test));
	return 0;
}
相关推荐
浮生如梦_36 分钟前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉3 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer3 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
wheeldown4 小时前
【数据结构】选择排序
数据结构·算法·排序算法
hikktn5 小时前
如何在 Rust 中实现内存安全:与 C/C++ 的对比分析
c语言·安全·rust
观音山保我别报错5 小时前
C语言扫雷小游戏
c语言·开发语言·算法
TangKenny6 小时前
计算网络信号
java·算法·华为
景鹤6 小时前
【算法】递归+深搜:814.二叉树剪枝
算法