二叉树概念、功能实现

本文介绍了二叉树的基本概念、结构及种类,并详细讲解了二叉树的遍历方式,包括深度遍历(前序、中序、后序)和广度遍历(层序)。此外,还提供了对称二叉树和子树问题的解决方案。



一、二叉树是什么?

1.基本概念

二叉树是从现实世界树的形状,抽象出来存储数据的一种结构。
二叉树每个节点至多存在两个子树节点,即简单把一棵树分为根节点,左子树节点,右子树节点。

2.基础结构

通常采用链式结构储存方式,方便访问、增加和删除数据。
一个数据储存域,左右节点指针域。
代码如下(示例)

typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* _left;
	struct BinaryTreeNode* _right;
}BTNode;

3.基本种类

简单划分为:普通二叉树、完全二叉树、满二叉树

普通:无排列顺序

在这里插入图片描述

完全:每层的节点必须从左至右排列存在
在这里插入图片描述

满:在完全二叉树基础之上,必须最后一层是满节点
在这里插入图片描述

二、二叉树的功能实现

1.二叉树的遍历方式

深度遍历:前序、中序、后序遍历

二叉树实例
选取

分类是根据访问根节点的时机来分,具体实现如下所示
代码如下(示例):

void BinaryTreePrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	//前序
	printf("%d ", root->data);
	BinaryTreePrevOrder(root->_left);
	BinaryTreePrevOrder(root->_right);
	//中序
	BinaryTreePrevOrder(root->_left);
	printf("%d ", root->data);
	BinaryTreePrevOrder(root->_right);
	//后序
	BinaryTreePrevOrder(root->_left);
	BinaryTreePrevOrder(root->_right);
	printf("%d ", root->data);
}

遍历效果
在这里插入图片描述

广度遍历:层序遍历

是采用一层从左至右的遍历方式,利用队列进行操作,主要思路是当出根节点,入左右子节点,循环往复下去直到队列为空为止,具体实现如下所示
代码如下(示例):

//建队列的实现程序这里不赘述
//主要代码如下
void BinaryTreeLevelOrder(BTNode* root)
{
	//创建队列
	Queue q;
	QueueInit(&q);
	//根节点入队
	if (root)
		QueuePush(&q, root);
	//循环遍历每一层
	while (!QueueEmpty(&q))//停止条件就是队列为空
	{
		BTNode* ret = QueueFront(&q);//取队首元素遍历
		printf("%d ", ret->data);
		QueuePop(&q);//出队
		if (ret->_left)//左子树节点入队
			QueuePush(&q, ret->_left);

		if (ret->_right)//右子树节点入队
			QueuePush(&q, ret->_right);
	}
	printf("\n");
	QueueDestroy(&q);//使用队列完成之后记得销毁队列结构,防止多次访问积累之后内存溢出
}

层序遍历效果在这里插入图片描述

2.二叉树几种常见的OJ例题

对称二叉树

在这里插入图片描述
解决思路:判断左右节点是否对称相等
代码如下(示例):

//子函数,把左右节点分别当成新的树,进行两棵树的对比
bool _isSymmetric(struct TreeNode* root1,struct TreeNode* root2)
{
    if(root1==NULL && root2==NULL)
        return true;
    if(root1==NULL || root2==NULL)
        return false;
    if(root1->val != root2->val)
        return false;
    return  _isSymmetric(root1->left,root2->right) && _isSymmetric(root1->right,root2->left);
}
//主程序
bool isSymmetric(struct TreeNode* root)
{
    return _isSymmetric(root->left,root->right);
}

另一棵树的子树

在这里插入图片描述
解题思路:从一棵树中找出与目标树完全相同的子树,循环遍历每个子树与之是否相同来判断
代码如下(示例):

isSameTree(struct TreeNode* p, struct TreeNode* q)
{
    //检查每一棵子树与目标树相同不
    if(p==NULL && q==NULL)
        return true;

    //其中一个为空
    if(p==NULL || q==NULL)
        return false;
    if(p->val!=q->val)
        return false;
    return  isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot)
{
    if(root==NULL)
        return NULL;
    //判断两树是否相等
    if(isSameTree(root,subRoot))//
        return true;
    //判断左右子树任意一个与其相等则相等
    return isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot);
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值