【数据结构】二叉树的构建与基本操作实现

这篇具有很好参考价值的文章主要介绍了【数据结构】二叉树的构建与基本操作实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【数据结构】二叉树的构建与基本操作实现,数据结构,数据结构,c语言,笔记,学习

👀樊梓慕:个人主页

 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》

🌝每一个不曾起舞的日子,都是对生命的辜负


目录

前言

1.前序建立二叉树

2.销毁二叉树

3.统计

4.查找值为x的节点

5.前中后序遍历

6.层序遍历

7.判断二叉树是否为完全二叉树

总结


前言

本篇文章博主将会与大家一起学习二叉树的构建与一些基本操作实现,那么对于二叉树来说:递归是不可绕开的话题,在本篇文章中你会看到很多的递归,递归的核心思想就是分割子问题,他异于我们之前学习的遍历枚举等思想,所以希望你能有所收获🌍


欢迎大家📂收藏📂以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。

=========================================================================文章来源地址https://www.toymoban.com/news/detail-722746.html

GITEE相关代码:🌟fanfei_c的仓库🌟

=========================================================================


1.前序建立二叉树

首先我们输入一段前序序列,用字符串存储,空节点的部分我们用字符'#' 替代,利用*pi作为下标,遍历该字符串。

前序:将字符赋给当前节点的数据域,*pi的值+1,给当前节点的左孩子执行相同操作,给当前节点的右孩子执行相同操作,采用递归方式完成。

那么你可以写出中序建立二叉树的算法么?

代码实现:

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

	root->_left = BinaryTreeCreate(a, pi);
	root->_right= BinaryTreeCreate(a, pi);
	return root;
}

为什么使用指针pi,而不用整型pi? 

  • 若传整型,在函数递归的过程中,由于函数栈帧的关系,整型pi的值不会保留,所以需要传递指针。

2.销毁二叉树

销毁二叉树比较简单。

注意:销毁二叉树采用的是后序遍历的方式,因为如果先销毁根节点,那么就找不到孩子节点了。 

代码实现: 

// 二叉树销毁
void BinaryTreeDestory(BTNode** root)
{
	if (*root)
	{
		BinaryTreeDestory(&(*root)->_left);
		BinaryTreeDestory(&(*root)->_right);
		free(*root);
        *root = NULL;
	}
}

3.统计

我们主要看一下统计第k层节点的算法:

如何判断何时递归到第k层呢?

  • 想要到达第k层,我们可以利用递归每次让k-1,当k的值为1的时候,那么此时我们就来到了第k层
  • 可以来到第k层的,也就是k==1时我们返回1
  • 递归还是采用双路递归,即返回左右子树的和即可

代码实现: 

//计算节点数
int BinaryTreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	return BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 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层节点个数(假设从第1层开始)
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	assert(k > 0);
	if (root == NULL)
	{
		return 0;
	}
	if (k == 1)
	{
		return 1;
	}
	return BinaryTreeLevelKSize(root->_left, k-1) 
        + BinaryTreeLevelKSize(root->_right, k-1);
    //递归每次让k-1,当k的值为1的时候,那么此时我们就来到了第k层
}

//二叉树深度
int BinaryTreeHeight(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	return fmax(BinaryTreeHeight(root->_left)
        , BinaryTreeHeight(root->_right))+1;
}

4.查找值为x的节点

该递归过程可以理解为前序思想,即如果根节点的值为x,那么肯定就可以直接返回,如果不同,我们就可以向左子树和右子树方向考虑,具体的设计可见代码。

代码实现:

BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->_data == x)
	{
		return root;
	}
	BTNode* ret = NULL;
	ret = BinaryTreeFind(root->_left,x);
	if (ret)
	{
		return ret;
	}
	ret = BinaryTreeFind(root->_right, x);
	if (ret)
	{
		return ret;
	}
	return NULL;
}

5.前中后序遍历

代码实现:

// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	printf("%c ", root->_data);
	BinaryTreeInOrder(root->_left);
	BinaryTreeInOrder(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;
	}
	BinaryTreeInOrder(root->_left);
	BinaryTreeInOrder(root->_right);
	printf("%c ", root->_data);
}

6.层序遍历

层序遍历的实现需要用到队列的逻辑结构。

首先将根节点入队,输出队首元素,并根据根节点找到左右孩子节点并入队,然后出队根节点,此时队首元素更新为根节点的左子树,再以此左子树为根循环这个过程,就能成功实现层序遍历。

【数据结构】二叉树的构建与基本操作实现,数据结构,数据结构,c语言,笔记,学习

代码实现:

void BinaryTreeLevelOrder(BTNode* root)
{
	Que q;
	QueueInit(&q);
	if (root)
		QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		printf("%c ", front->_data);
		if (front->_left)
		{
			QueuePush(&q, front->_left);
		}
		if (front->_right)
		{
			QueuePush(&q, front->_right);
		}
		QueuePop(&q);
	}
	QueueDestroy(&q);
	return;
}

7.判断二叉树是否为完全二叉树

完全二叉树通俗的讲就是每个节点都是连续的,不存在某个节点之前存在空节点的情况,那么根据这个特性,我们同样可以利用层序遍历的思想,利用队列的逻辑结构来解决。

思路:与层序遍历不同的是,我们不管左右子树是否为空都入队,这样在循环结束时,队列中要么全为空,此时证明该二叉树是完全二叉树,如果队列中但凡存在一个不为空的情况,那就证明该二叉树不为完全二叉树。

【数据结构】二叉树的构建与基本操作实现,数据结构,数据结构,c语言,笔记,学习

代码实现:

bool BinaryTreeComplete(BTNode* root)
{
	Que q;
	QueueInit(&q);
	if (root)
		QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		if (front == NULL)
		{
			break;
		}
		QueuePush(&q, front->_left);
		QueuePush(&q, front->_right);
		QueuePop(&q);
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front != NULL)
		{
			QueueDestroy(&q);
			return false;
		}
	}
	QueueDestroy(&q);
	return true;
}

注意:循环条件中QueueEmpty判断的是队列是否为空,即队首指针指向是否为空,而第一次遍历队列判断的条件是队首元素的数据域是否为NULL,两者不一样。 


总结

递归是一种十分巧妙的方法,他的特点是可以拆分子问题,将大问题简化为可以解决小问题,但不知道你是否和我一样,思考问题好像已经习惯了遍历枚举求解的思想,那么下一篇文章我会为大家带来二叉树的OJ题系列,强化对于递归问题的理解,让我们一起努力吧🌝

=========================================================================

如果你对该系列文章有兴趣的话,欢迎持续关注博主动态,博主会持续输出优质内容

🍎博主很需要大家的支持,你的支持是我创作的不竭动力🍎

🌟~ 点赞收藏+关注 ~🌟

=========================================================================

到了这里,关于【数据结构】二叉树的构建与基本操作实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】二叉树的存储与基本操作的实现

    二叉树的存储结构分为: 顺序存储 和类似于 链表的链式存储 这里博主讲一下链式存储 二叉树的链式存储是通过一个一个的节点引用起来的,常见的表示方式有 二叉和三叉 表示方式 二叉表示: 三叉表示: 这里博主主要讲解一下孩子表示法 在学习二叉树的基本操作前,需

    2024年02月04日
    浏览(47)
  • 数据结构实验报告,二叉树的基本操作(C语言)

    作者:命运之光 专栏:数据结构 实验六 二叉树的基本操作 实验环境:Visual C++或Dev C++ 实验目的: 1、掌握二叉树创建; 2、掌握二叉树的遍历及常用算法。 实验内容: 通过完全前序序列创建一棵二叉树,完成如下功能: 1)输出二叉树的前序遍历序列; 2)输出二叉树的中序遍

    2024年02月09日
    浏览(37)
  • 二叉树的基本操作-C语言实现-数据结构作业

    目录  (1)二叉树的创建; (2)二叉树的先序、中序和后序遍历输出; (3)输出二叉树的叶子节点和度为2的节点的数量; (4)输出二叉树的深度; (5)将二叉树所有节点的左右子树互换(左子树变右子树,右子树变左子树); (6)参考书上,二叉树按层次输出(一行输出一层); (7)删除二

    2024年02月04日
    浏览(47)
  • 数据结构和算法学习记录——初识二叉树(定义、五种基本形态、几种特殊的二叉树、二叉树的重要性质、初识基本操作函数)

    目录 二叉树的定义 二叉树具体的五种基本形态 1.空树 2.只有一个节点 3.有左子树,但右子树为空 4.有右子树,但左子树为空  5.左右两子树都不为空 特殊二叉树 斜二叉树 满二叉树  完全二叉树 二叉树的几个重要性质 初识二叉树的几个操作函数  二叉树T: 一个有穷的节点

    2024年02月03日
    浏览(60)
  • 【数据结构之二叉树的构建和遍历】

    前言: 前篇学习了 数据结构之树和二叉树的基本概念知识,那么这篇继续完善二叉树的相关知识并完成实现二叉树的构建和遍历的内容。 / 知识点汇总 / 因为前篇已经非常详细的单独学习了数和二叉树的基本知识概念,那么这里就简单回顾一下即可。 概念 : 二叉树(Bina

    2024年02月21日
    浏览(47)
  • 初阶数据结构之---二叉树链式结构(二叉树的构建,二叉树的前序,中序,后序和层序遍历,计算二叉树结点个数,第k层结点个数,叶子结点个数,判断是否为完全二叉树)

    本篇博客是初阶数据结构树的收尾,将会讲掉 基本二叉树链式结构的具体内容和实现,包括二叉树的构建,前序遍历,中序遍历,后序遍历和层序遍历,计算二叉树结点个数,第k层结点个数,二叉树叶子结点个数,以及判断一个二叉树是否为完全二叉树 。话不多说,开始我

    2024年03月24日
    浏览(50)
  • 【数据结构】树、二叉树的概念和二叉树的顺序结构及实现

    之前我们学习了顺序表、链表以及栈和队列这些数据结构,但这些数据结构都是线性的(一对一)。接下来要学习 非线性的数据结构——树(二叉树) ,相比前面的,树的结构更加复杂,话不多说,直接进入正题吧。 树是一种 非线性的数据结构 ,它是 一对多(也有可能是

    2024年02月07日
    浏览(41)
  • 数据结构——二叉树的链式结构

      个人主页 : 日刷百题 系列专栏 : 〖C语言小游戏〗〖Linux〗〖数据结构〗  〖C语言〗 🌎 欢迎各位 → 点赞 👍+ 收藏 ⭐️+ 留言 📝  ​ 这里我们使用先序遍历的思想来创建二叉树,这里的内容对于刚接触二叉树的朋友可能有些难理解,不妨先看完下面的二叉树各种遍历

    2024年02月05日
    浏览(47)
  • 【数据结构】二叉树的链式结构

    学习链式二叉树要知道三种遍历方式,便于对二叉树的节点以及左子树和右子树进行操作。 前序遍历:根、左子树、右子树 中序遍历:左子树、根、右子树 后序遍历:左子树、右子树、根 以下图为例: 得到的结果: 前序遍历:1 2 3 4 5 6 中序遍历:3 2 1 5 4 6 后序遍历:3 2

    2024年02月08日
    浏览(56)
  • 数据结构:二叉树的链式结构

    朋友们、伙计们,我们又见面了,本期来给大家解读一下链式二叉树的相关知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! 数据结构与算法专栏 :数据结构与算法 个  人  主  页 :stackY、 C 语 言 专 栏 :C语言:从入门到精通 目录 前言

    2024年02月07日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包