二叉树从概念到代码实现(详细)

目录

二叉树的概念:

特殊的二叉树:

二叉树的存储结构:

二叉树的遍历

简单二叉树的创建

1、简单二叉树的创建

 2、二叉树的遍历(遍历思想是一样的,所以真正二叉树的遍历也是如此)

3、求简单二叉树的节点个数以及高度 

4、二叉树中值=x的结点查找

 5、二叉树第k层节点个数

6、真正二叉树的创建 

7、是否是完全二叉树的判断


二叉树的概念:

一个二叉树是结点的有限集合、该集合:

1、或者为空

2、由一个根结点加上两颗别称为左子树和右子树的二叉树组成。

 

                             二叉树

 注意:

1、二叉树不存在度大于2的结点

2、二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树

特殊的二叉树:

1、满二叉树:每一层的结点数都达到最大值

2、完全二叉树:当且仅当每一个结点都与深度为K的满二叉树中编号1~n的结点一一对应时,称之为完全二叉树(易看出:满二叉树是一种特殊的完全二叉树) 

二叉树的五大性质自行了解。

二叉树的存储结构:

1、顺序存储——使用数组来存储,但一般只适用于完全二叉树,不然会造成空间的浪费。

2、链式存储——使用链表示结点之间的逻辑关系,一般使用二叉链表。

二叉树的遍历

二叉树的遍历是按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次。

按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:

  • 前序遍历(也叫先序遍历):访问根节点的操作发生在遍历其左右子树之前。
  • 中序遍历:访问根节点的操作发生在遍历其左右子树之中。
  • 访问根结点的操作发生在访问其左右子树之后。

此外,二叉树还有层序遍历:

从所在根结点出发,自上而下,自左而右逐层访问树的结点的过程就是层序遍历。 

typedef int BTDataType;

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

简单二叉树的创建

 在对二叉树还不熟悉时,我们先实现一个简单的二叉树,如上图。

1、简单二叉树的创建

我们需要:

1、创建六个结点

2、将这六个结点连接起来

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


typedef int BTDataType;

typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;


//创建结点
BTNode* BuyBTNode(BTDataType data);
//六个节点的简单二叉树的创建
BTNode* BinaryTreeCreate();

//创建结点
BTNode* BuyBTNode(BTDataType data)
{
	BTNode* newNode = (BTNode*)malloc(sizeof(BTNode));
	if (newNode == NULL)
	{
		assert(0);
		return NULL;
	}
	newNode->data = data;
	newNode->left = NULL;
	newNode->right = NULL;
	return newNode;
}


// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate()
{
	BTNode* node1 = BuyBTNode(1);
	BTNode* node2 = BuyBTNode(2);
	BTNode* node3 = BuyBTNode(3);
	BTNode* node4 = BuyBTNode(4);
	BTNode* node5 = BuyBTNode(5);
	BTNode* node6 = BuyBTNode(6);
	node1->left = node2;
	node2->left = node3;
	node1->right = node4;
	node4->left = node5;
	node4->right = node6;
	return node1;//返回根结点
}

 2、二叉树的遍历(遍历思想是一样的,所以真正二叉树的遍历也是如此)

//简单二叉树的前序遍历
void PreOrder(BTNode* root);

//简单二叉树的中序遍历
void InOrder(BTNode* root);

//简单二叉树的后序遍历
void PostOrder(BTNode* root);

//二叉树的层序遍历
void LevelOrder(BTNode*root);

void PreOrder(BTNode* root)
{
	if (NULL == root)
		return;
	printf("%d ", root->data);
	PreOrder(root->left);
	PreOrder(root->right);
}

void InOrder(BTNode* root)
{
	if (NULL == root)
		return;
	InOrder(root->left);
	printf("%d ", root->data);
	InOrder(root->right);
}

void PostOrder(BTNode* root)
{
	if (NULL == root)
		return;
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->data);
}

void LevelOrder(BTNode*root)
{
	Queue q;
	if (NULL == root)
		return;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* cur = QueueFront(&q);
		QueuePop(&q);
		printf("%d ", cur->data);
		//如果cur有左孩子,让它的左孩子入队列
		if (cur->left)
			QueuePush(&q, cur->left);
		if (cur->right)
			QueuePush(&q, cur->right);
	}
	QueueDestroy(&q);
}

3、求简单二叉树的节点个数以及高度 

//二叉树的高度
int BinaryHeight(BTNode* root);
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);

int BinaryTreeSize(BTNode* root)
{
	if (NULL == root)
		return;
	return BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}

int BinaryHeight(BTNode* root)
{
	if (NULL == root)
		return 0;
	int leftHeight = BinaryHeight(root->left);
	int rightHeight = BinaryHeight(root->right);
	return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}

int BinaryTreeLeafSize(BTNode* root)
{
	if (NULL == root)
		return 0;
	if (NULL == root->left && NULL == root->right)
		return 1;
	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

4、二叉树中值=x的结点查找

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

BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	BTNode* ret = NULL;
	if (NULL == root)
		return NULL;
	if (root->data = x)
		return root;
	ret = BinaryTreeFind(root->left, x);
	if (ret)
		return ret;
		return BinaryTreeFind(root->right,x);
}

 5、二叉树第k层节点个数

// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if (NULL == root || k <= 0)
		return 0;
	if (k == 1)
		return 1;
	return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}

在看了上述这个简单二叉树的创建以后,真正二叉树的创建也是一样的利用二叉树递归的思想,来进行创建。 

6、真正二叉树的创建 

//真正二叉树的创建

// 通过前序遍历的数组构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int invalid);

BTNode* __BinaryTreeCreate(BTDataType* a, int n, int *index,int invalid)
{
	BTNode* root = NULL;
	if (*index < n && a[*index]!= invalid)
	{
		root = BuyBTNode(a[*index]);//创建根节点
		//递归创建根的左子树
		(*index)++;
		root->left = __BinaryTreeCreate(a, n, index, invalid);
		//递归创建根的右子树
		(*index)++;
		root->right = __BinaryTreeCreate(a, n, index, invalid);
	}
	return root;
}

BTNode* BinaryTreeCreate(BTDataType* a, int n, int invalid)
{
	int index = 0;
	return __BinaryTreeCreate(a, n, &index, invalid);
}
//用户可以通过直接调用BinaryTreeCreate(BTDataType* a, int n, int invalid)函数来进行二叉树的创建

主函数传递数组时自己定义即可。 

7、是否是完全二叉树的判断

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

int BinaryTreeComplete(BTNode* root)
{
	Queue q;
	if (NULL == root)
		return 1;
	//1、按照层序的方式找出第一个不饱和的结点——采用队列数据结构
	QueueInit(&q);
	QueuePush(&q, root);
	int flag = 0;
	int isCompleteTree = 1;
	while (!QueueEmpty(&q))
	{
		BTNode* cur = QueueFront(&q);
		QueuePop(&q);
		if (flag)
		{
			if (cur->left || cur->right)
			{
				isCompleteTree = 0;
				break;
			}
		}
		else
		{
			if (cur->left && cur->right)
			{
				QueuePush(&q, cur->left);
				QueuePush(&q, cur->right);
			}
			else if (cur->left)
			{
				QueuePush(&q, cur->left);
				flag = 1;
			}
			else if (cur->right)
			{
				isCompleteTree = 0;
			}
			else
				flag = 1;
		}
	}
	QueueDestroy(&q);
	return isCompleteTree;
}

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值