实现二叉树 C语言版

实现二叉树



前言

普通二叉树的增删改查没有什么意义,但掌握普通二叉树的实现对递归的掌握和后续学习AVL树、红黑树等有很大帮助。


1. 二叉树节点定义

typedef char DataType;

typedef struct BinaryTreeNode
{
    
    
	DataType _data;
	struct BinaryTreeNode* _left;
	struct BinaryTreeNode* _right;
}Node;



2. 二叉树的接口


// 通过前序遍历的字符串"ABD##E#H##CF##G##" 重构二叉树
//前序 ABD##E#H##CF##G##
//中序 #D#B#E#H#A#F#C#G#
Node* BinaryTreeCreate(DataType* a, int* pi);
// 销毁
void BinaryTreeDestory(Node* root);
// 节点个数
int BinaryTreeSize(Node* root);
// 叶子节点个数
int BinaryTreeLeafSize(Node* root);
// 第k层节点个数
int BinaryTreeLevelKSize(Node* root, int k);
// 查找值为x的节点
Node* BinaryTreeFind(Node* root, DataType x);
// 前序遍历 
void BinaryTreePrevOrder(Node* root);
// 中序遍历
void BinaryTreeInOrder(Node* root);
// 后序遍历
void BinaryTreePostOrder(Node* root);
// 层序遍历
void BinaryTreeLevelOrder(Node* root);
// 是否是完全二叉树
bool BinaryTreeComplete(Node* root);
// 返回二叉树高度
int BinaryTreeDepth(Node* root);


3. 接口实现


3.1 创建二叉树


// 通过前序遍历的字符数组"ABD##E#H##CF##G##"构建二叉树
Node* BinaryTreeCreate(DataType* arr, int* pi)
{
    
    
	if (arr[*pi] == '#')
	{
    
    
		(*pi)++;
		return NULL;
	}

	Node* newNode = (Node*)malloc(sizeof(Node));
	if (!newNode)
	{
    
    
		printf("malloc fail\n");
		exit(-1);
	}

	newNode->_data = arr[(*pi)++];

	newNode->_left = BinaryTreeCreate(arr, pi);
	newNode->_right = BinaryTreeCreate(arr, pi);

	return newNode;
}

3.2 销毁二叉树

// 二叉树销毁
// 通过后续遍历销毁二叉树
void BinaryTreeDestory(Node* root)
{
    
    
	if (!root)
		return;
	BinaryTreeDestory(root->_left);
	BinaryTreeDestory(root->_right);
	free(root);
}

3.3 二叉树高度

// 思路:depth = 根节点高度 + max(左子树高度,右子树高度)
int BinaryTreeDepth(Node* root)
{
    
    
	if (!root)
		return 0;

	int left = BinaryTreeDepth(root->_left);
	int right = BinaryTreeDepth(root->_right);

	return left > right ? 1 + left : right + 1;
}

3.4二叉树节点个数

int BinaryTreeSize(Node* root)
{
    
    
	return !root ? 0 : 1
		+ BinaryTreeSize(root->_left)
		+ BinaryTreeSize(root->_right);
}

3.4 二叉树叶子节点个数

// 二叉树叶子节点个数
int BinaryTreeLeafSize(Node* root)
{
    
    
	if (!root)
		return 0;

	if (root->_left == NULL && root->_right == NULL)
		return 1;

	return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}

3.5 二叉树第k层节点个数

// 二叉树第k层节点个数
int BinaryTreeLevelKSize(Node* root, int k)
{
    
    
	if (!root)
		return 0;

	if (k == 1)
		return 1;

	return BinaryTreeLevelKSize(root->_left, k - 1)
		+ BinaryTreeLevelKSize(root->_right, k - 1);
}

3.6 查找值为x的节点

// 二叉树查找值为x的节点
Node* BinaryTreeFind(Node* root, DataType x)
{
    
    
	if (!root)
		return NULL;

	if (root->_data == x)
		return root;

	return BinaryTreeFind(root->_left, x) ||
		BinaryTreeFind(root->_right, x);
}

3.7 前、中、后序遍历

// 二叉树前序遍历 
void BinaryTreePrevOrder(Node* root)
{
    
    
	if (!root)
	{
    
    
		printf("# ");
		return;
	}

	printf("%c ", root->_data);
	BinaryTreePrevOrder(root->_left);
	BinaryTreePrevOrder(root->_right);
}


// 二叉树中序遍历
void BinaryTreeInOrder(Node* root)
{
    
    
	if (!root)
	{
    
    
		printf("# ");
		return;
	}
	BinaryTreeInOrder(root->_left);
	printf("%c ", root->_data);
	BinaryTreeInOrder(root->_right);
}

// 二叉树后序遍历
void BinaryTreePostOrder(Node* root)
{
    
    
	if (!root)
	{
    
    
		printf("# ");
		return;
	}
	BinaryTreePostOrder(root->_left);
	BinaryTreePostOrder(root->_right);
	printf("%c ", root->_data);
}

3.8 层序遍历

// 层序遍历
// ABD##E#H##CF##G##
// 借助队列实现
void BinaryTreeLevelOrder(Node* root)
{
    
    
	int depth = BinaryTreeDepth(root);
	Node** que = (Node*)malloc(sizeof(Node*) * (int)pow(2, depth));

	int head = -1;
	int tail = -1;

	que[++tail] = root;

	while (head < tail)
	{
    
    
		printf("%c ", que[++head]->_data);

		if (que[head]->_left)
			que[++tail] = que[head]->_left;

		if (que[head]->_right)
			que[++tail] = que[head]->_right;
	}

	free(que);
}

3.9 判断是否完全二叉树

// 判断二叉树是否是完全二叉树
// 完全二叉树 ABD##E##CF##G##
bool BinaryTreeComplete(Node* root)
{
    
    
	if (!root) return false;

	int depth = BinaryTreeDepth(root);
	int newDepth = depth + 1;
	Node** que = (Node*)malloc(sizeof(Node*) * (int)pow(2, newDepth));

	int head = -1;
	int tail = -1;

	que[++tail] = root;

	while (head < tail)
	{
    
    
		head++;
		if (que[head] == NULL)
			break;

		que[++tail] = que[head]->_left;
		que[++tail] = que[head]->_right;
	}

	while (head < tail)
	{
    
    
		if (que[head] != NULL)
			return false;
		head++;
	}

	free(que);
	return true;
}

4 测试

通过控制台输入此二叉树的前序遍历 。

在这里插入图片描述

代码示例:

#include "BinaryTree.h"

void test1()
{
    
    
	char arr[100];
	scanf("%s", arr);

	//创建二叉树
	int i = 0;
	Node* root = BinaryTreeCreate(arr, &i);

	printf("二叉树节点总数为:%d\n", BinaryTreeSize(root));
	printf("二叉树叶子节点总数为:%d\n", BinaryTreeLeafSize(root));
	int k = 3;
	printf("二叉树第%d层节点总数为:%d\n", k, BinaryTreeLevelKSize(root, k));

	printf("二叉树深度为:%d\n", BinaryTreeDepth(root));
	

	if (BinaryTreeComplete(root))
		printf("是完全二叉树\n");
	else
		printf("不是完全二叉树\n");


	char c = 'A';
	Node* find =  BinaryTreeFind(root,c);
	if (find)
		printf("找到了\n");
	else
		printf("没找到\n");


	//中序遍历
	printf("中序遍历: ");
	BinaryTreeInOrder(root);
	printf("\n");


	//层序遍历
	printf("层序遍历: ");
	BinaryTreeLevelOrder(root);
	printf("\n");


	BinaryTreeDestory(root);
	root = NULL;
}

int main()
{
    
    
	test1();
}

输出:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/juggte/article/details/120238658