【数据结构】—详解二叉树— ⌈知识点总结⌋ 和 ⌈常见力扣题目⌋ 确定不来看吗?

前言

❤️ 铁汁们大家好,欢迎大家来到出小月的博客里, 🤗🤗🤗之前呢,我分享了数据结构的栈和队列。。。。今天呢,给大家分享关于树的内容包括了树的结构、遍历和一些题目,希望大家看完我这篇文章都能够“涨芝士”,感觉小月写的还不错的话,记得👍🏻点赞加关注😘鼓励一下博主哦,不然下次可找不到我啦❗❗


作者简介

❤️ 作者的gitee:出小月;

❤️ 作者的主页:出小月的《程序员历险记》

❤️专栏:《C语言》,《数据结构初阶》

😊希望大家都能够:好好学习,天天编程❗❗❗


文章目录

    • 前言
    • 作者简介
    • 一、树概念及结构
    • 二、二叉树结构及遍历
    • 1、二叉树性质
    • 1、二叉树结构
    • 2、特殊的二叉树
      • 1️⃣ 满二叉树
      • 2️⃣完全二叉树
    • 3、二叉树的遍历
      • 1️⃣前序遍历
      • 2️⃣中序遍历
      • 3️⃣后序遍历
      • 4️⃣层序遍历
    • 三、二叉树常见OJ题练习
    • 1、树的结点的个数
    • 2、叶子节点的个数
    • 3、主函数
    • 总结

一、树概念及结构

🤗之前呢,我分享了顺序表、链表、栈和队列。这些都是线性结构,今天呢分享树的知识点,树呢是一种非线性的数据结构。把它叫做树呢?是因为它看起来像一颗倒挂的树,也就是说根朝上,而叶子朝下。

在这里插入图片描述

🤗这就是一棵树,那它怎么表示的呢?我们一般用左孩子、右兄弟。

typedef char tdatatype;
struct node
{
	struct node* firstchild;//第一个孩子节点
	struct node* nextbrother;//指向其下一个兄弟结点
	tdatatype data;
};

二、二叉树结构及遍历

1、二叉树性质

1、若根节点层数为i,则一颗非空二叉树的第i层上最多有2^(i-1);

2、若根节点层数为i,则深度为H的最大二叉树的最大节点数为(2^H)-1;

3、对于任何一颗二叉树,如果度为0其叶节点个数为n0,度为2的分支节点个数为n2,则有

n0=n2+1;

1、二叉树结构

🐹我们重点说的是二叉树。。。

任何一个二叉树都可以分成三个部分:

0️⃣ 根节点

1️⃣ 左子树

2️⃣ 右子树

我们这主要用的是分治算法:分而治之,大问题分成类似子问题,子问题再分成子问题……

那这是不是可以用递归啦?直到子问题不可再分割❗❗❗

在这里插入图片描述

🐷就像这个二叉树本来可以分为以A结点为根节点,还有左子树,右子树;

然后左子树又可以分成以B为根节点,还有左子树,右子树;

右子树也可以分成以C为根节点,还有左子树,右子树;

2、特殊的二叉树

1️⃣ 满二叉树

一个二叉树,如果每一层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是,如果一个二叉树N层,且总结点的个数是(2^N)-1,则它就是满二叉树。

2️⃣完全二叉树

完全二叉树由满二叉树而引出来,对于深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1-n的结点一一对应时称之为完全二叉树。

在这里插入图片描述

满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树

3、二叉树的遍历

在这里插入图片描述

1️⃣前序遍历

🐱就是先访问根节点,再访问左子树,最后访问右子树

就上面的树,我们先访问A结点

再访问左子树:左子树先访问B结点,再访问B结点的左子树D结点,然后再访问B结点的右子树,右子树先访问E结点,没有左子树,再访问H结点;

接下来访问右子树:先访问C结点,在访问左子树F结点,再访问右子树G结点

递归图就是这⬇️,大家一定要自己动手画一画,更加容易理解。。。

在这里插入图片描述

递归展开图比较复杂就展开一个简单的吧上面的⬆️

在这里插入图片描述

代码如下:

void prevorder(bitree* root)//递归前序 
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%c ", root->data);
	prevorder(root->left);
	prevorder(root->right);
}

2️⃣中序遍历

🐱就是先访问左子树,再访问根节点,最后访问右子树

代码如下:

void inorder(bitree* root)//递归中序
{
	if (root == NULL)
	{
	   printf("NULL ");
	   return;
	}
	inorder(root->left);
	printf("%c", root->data);
	inorder(root->right);
}

3️⃣后序遍历

🐱就是先访问根结点,再访问左子树,最后访问右子树

代码如下:

void lastorder(bitree* root)//递归后序
{
    if (root == NULL)
	{
	   printf("NULL ");
	   return;
	}
	lastorder(root->left);
	lastorder(root->right);
	printf("%c", root->data);
}

4️⃣层序遍历

🤗层序遍历的核心:首先将二叉树的根节点入队中,判断队列不为空,就输出队头的元素,

如果这个结点有孩子,就将孩子入队,将遍历过的节点出队列,循环以上操作,直到树为空

typedef struct queuenode
{
	struct queuenode* next;
	char data;
}qnode;
typedef struct queue
{
	qnode* head;
	qnode* tail;
}queue;
void levelorder(bitree* root)//非递归的层序遍历(用队列实现)核心:上一层带下一层
{
	queue q;
	queueinit(&q);
	if (root)
	{
		queuepush(&q, root);//头结点进栈
		while (!queueempty(&q))//如果这个队列不为空
		{
			bitree* front = queuefront(&q);//就出栈
			queuepop(&q);
			printf("%c", front->data);//并打印
			if (front->left)//如果这个结点的左子树存在就进队列
			{
				queuepush(&q, front->left);
			}
			if (front->right)//如果这个结点的右子树存在就进队列
			{
				queuepush(&q, front->right);
			}
		}
	}
}

三、二叉树常见OJ题练习

1、树的结点的个数

🐻这里用了一个三目运算符,如果这个结点是空就是0个结点,如果不为空就递归的遍历左子树的结点,和右子树的结点,还要加上根节点这个结点

int treesize(bitree* root)
{
	return root == NULL ? 0 : treesize(root->left) + treesize(root->right) + 1;
}

2、叶子节点的个数

🐻叶子节点就是左子树和右子树都为0的结点,因此只一左子树和右子树都为0的这个结点返回1,然后递归遍历左子树,右子树。

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

3、主函数

🐻这里我建了一棵树

int main()
{
	bitree* A = (bitree*)malloc(sizeof(bitree));
	A->data = 'A';
	A->left = NULL;
	A->right = NULL; 
	bitree* B = (bitree*)malloc(sizeof(bitree));
	B->data = 'B';
	B->left = NULL;
	B->right = NULL;
	bitree* C = (bitree*)malloc(sizeof(bitree));
	C->data = 'C';
	C->left = NULL;
	C->right = NULL;
	bitree* D = (bitree*)malloc(sizeof(bitree));
	D->data = 'D';
	D->left = NULL;
	D->right = NULL;
	bitree* E = (bitree*)malloc(sizeof(bitree));
	E->data = 'E';
	E->left = NULL;
	E->right = NULL;
	A->left = B;
	A->right = C;
	B->left = D;
	B->right = E;
	prevorder(A);//前序遍历
	return 0;
}

总结

🤗🤗今天关于树的知识点就分享到这里了,感觉小月写的还不错的话,记得点赞加关注哦👍👍,小月一直会分享记录自己的学习过程哦❗❗❗

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://www.net2asp.com/1207d6e779.html