实现二叉树

文章提供了一组C语言代码,用于实现二叉树的层次遍历。它首先定义了一个队列结构,包括初始化、入队、出队等操作。接着,定义了二叉树的结构和相关操作,如创建、销毁、遍历等。在二叉树的层序遍历中,利用队列进行节点的处理。最后,通过一系列测试函数展示了这些功能的使用。
摘要由CSDN通过智能技术生成

目录

一、为实现二叉树的层序遍历要借用队列的功能

1.Queue.c

2.Queue.h

二、二叉树

1.BinaryTree.h

2.BinaryTree.c

3.Test.c


一、为实现二叉树的层序遍历要借用队列的功能

1.Queue.c


#include "Queue.h"

//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = NULL;
	pq->tail = NULL;
}

//入队---队尾入
void Queuepush(Queue* pq, DataTyPe x)
{
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	//判断内存申请是否成功
	if (newnode == NULL)
	{
		perror("malloc");
		return;
	}
	else
	{
		newnode->data = x;
		newnode->next = NULL;
	}

	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;

	}

}

//出队--队头出
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	//当只有一个数据时---这样做可以防止tail成为野指针
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}

//计算队列数据个数
int QueueSize(Queue* pq)
{
	assert(pq);
	int size = 0;
	QNode* cur = pq->head;
	while (cur)
	{
		size++;
		cur = cur->next;
	}

	return size;
}
//找到队头的数据
DataTyPe QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->head->data;
}

//找到队尾的数据
DataTyPe QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->tail->data;
}
//判空
bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->head == NULL;
}

//销毁
void QueueDestory(Queue* pq)
{
	assert(pq);


	QNode* cur = pq->head;

	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
}

2.Queue.h

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


typedef struct BinaryTreeNode* DataTyPe;

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

typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;
//初始化
void QueueInit(Queue* pq);

//入队---队尾入
void Queuepush(Queue* pq, DataTyPe x);

//出队--队头出
void QueuePop(Queue* pq);

//计算队列数据个数
int QueueSize(Queue* pq);

//找到队头的数据
DataTyPe QueueFront(Queue* pq);

//找到队尾的数据
DataTyPe QueueBack(Queue* pq);
//判空
bool QueueEmpty(Queue* pq);

//销毁
void QueueDestory(Queue* pq);

二、二叉树

1.BinaryTree.h


#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.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);
// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root);

2.BinaryTree.c


#include "BinaryTree.h"
#include "Queue.h"



// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{
	assert(a);
	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;

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


	if (root == NULL)
		return;

	//后序销毁
	BinaryTreeDestory(root->left);
	BinaryTreeDestory(root->right);

	free(root);
}
// 二叉树节点个数---左子树节点个数加右子树节点个数 + 1
int BinaryTreeSize(BTNode* root)
{
	

	if (root == NULL)
		return 0;

	return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}
// 二叉树叶子节点个数---左子树叶子节点个数加右子树叶子节点个数 + 1
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)
{

	if (root == NULL)
		return 0;

	//到达k层
	if (k == 1)
		return 1;

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

}
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
		return NULL;
	
	if (root->data == x)
		return root;

	return BinaryTreeFind(root->left, x) ||
		BinaryTreeFind(root->right, x);
}
// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root)
{
	if (root == NULL)
		return;
	printf("%c ", root->data);
	BinaryTreePrevOrder(root->left);
	BinaryTreePrevOrder(root->right);
}
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
	if (root == NULL)
		return;
	
	BinaryTreeInOrder(root->left);
	printf("%c ", root->data);
	BinaryTreeInOrder(root->right);
}
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
	if (root == NULL)
		return;

	BinaryTreePostOrder(root->left);
	BinaryTreePostOrder(root->right);
	printf("%c ", root->data);
}
// 层序遍历--先入根,出一个节点时如它的左右孩子
void BinaryTreeLevelOrder(BTNode* root)
{
	Queue q;

	QueueInit(&q);

	if (root != NULL)
	{
		Queuepush(&q, root);
	}

	while (!QueueEmpty(&q))
	{
		DataTyPe front = QueueFront(&q);
		QueuePop(&q);

		printf("%c ", front->data);
		if(front->left)
			Queuepush(&q, front->left);
		if(front->right)
			Queuepush(&q, front->right);
	}

	printf("\n");

	QueueDestory(&q);
}
// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
	{
		Queuepush(&q, root);
	}
	
	while (!QueueEmpty(&q))
	{
		DataTyPe front = QueueFront(&q);
		QueuePop(&q);
		//遇到空退出
		if (front == NULL)
			break;

		//空也入
		Queuepush(&q, front->left);
		Queuepush(&q, front->right);
	}

	//检查是否有非空,有这不是完全二叉树

	while (!QueueEmpty(&q))
	{
		DataTyPe front = QueueFront(&q);
		QueuePop(&q);

		if (front != NULL)
		{
			QueueDestory(&q);

			return false;
		}
	}

	QueueDestory(&q);
	return true;
}

3.Test.c


#include "BinaryTree.h"


void Test1()
{
	char a[] = { "ABD##E#H##CF##G##" };
	int i = 0;
	BTNode* root = BinaryTreeCreate(a, &i);

	BinaryTreePrevOrder(root);
	printf("\n");
	BinaryTreeInOrder(root);
	printf("\n");
	BinaryTreePostOrder(root);
	printf("\n");

	BinaryTreeDestory(root);
}

void Test2()
{
	char str[] = { "ABD##E#H##CF##G##" };
	int i = 0;
	BTNode* root = BinaryTreeCreate(str, &i);

	int a = BinaryTreeSize(root);

	int b = BinaryTreeLeafSize(root);
	int k = 3;
	int c = BinaryTreeLevelKSize(root, k);
	printf("二叉树节点个数:%d\n二叉树叶子节点个数:%d\n二叉树第%d层节点个数%d\n", a, b, k, c);
	BinaryTreeDestory(root);
}

void Test3()
{
	char str[] = { "ABD##E#H##CF##G##" };
	int i = 0;
	BTNode* root = BinaryTreeCreate(str, &i);
	char x = 'A';
	BTNode* findroot = BinaryTreeFind(root, x);
	if (findroot == NULL)
	{
		printf("找不到%c\n", x);
		return;
	}
	printf("找到%c\n", findroot->data);

	BinaryTreeDestory(root);

}
//测试层序遍历
void Test4()
{
	char str[] = { "ABD##E#H##CF##G##" };
	int i = 0;
	BTNode* root = BinaryTreeCreate(str, &i);
	BinaryTreeLevelOrder(root);

	BinaryTreeDestory(root);
}

//测试是否为完全二叉树
void Test5()
{
	char str1[] = { "ABD##E##CF##G##" };
	int i = 0;
	BTNode* root1 = BinaryTreeCreate(str1, &i);
	char str2[] = { "ABD##E#H##CF##G##" };
	int j = 0;
	BTNode* root2 = BinaryTreeCreate(str2, &j);
	if (BinaryTreeComplete(root1))
		printf("is full binary tree\n");
	else
		printf("no full binary tree\n");
	if (BinaryTreeComplete(root2))
		printf("is full binary tree\n");
	else
		printf("no full binary tree\n");

	BinaryTreeDestory(root1);
	BinaryTreeDestory(root2);
}


int main()
{
	//Test1();
	//Test2();
	//Test3();
	//Test4();
	Test5();

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值