数据结构(初阶)(七)----树和二叉树(前中后序遍历)

实现链式结构的二叉树

⽤链表来表⽰⼀棵⼆叉树,即⽤链来指⽰元素的逻辑关系。 通常的⽅法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别⽤来给出该结点左孩⼦和右孩⼦所在的链结点的存储地址 ,

其结构如下:

c 复制代码
typedef int BTDataType; // ⼆叉链 
typedef struct BinaryTreeNode 
{ 
	struct BinTreeNode* left; // 指向当前结点左孩⼦ 
	struct BinTreeNode* right; // 指向当前结点右孩⼦ 
	BTDataType val; // 当前结点值域 
}BTNode;

遍历

前中后序遍历

前序遍历

也叫先根遍历

先遍历根节点,再遍历左子树,最后遍历右子树

左右根

A->B->D->NULL->NULL->NULL->C->E->NULL->NULL->F->NULL->NULL

c 复制代码
//前序遍历--根左右
void PreOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%c ", root->data);
	PreOrder(root->left);
	PreOrder(root->right);
}
中序遍历

先遍遍历左子树,,再遍历根节点,最后遍历右子树

左根右

NULL->D->NULL->B->NULL->A->NULL->E->NULL->C->NULL->F->NULL

c 复制代码
//中序遍历--左根右
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	InOrder(root->left);
	printf("%c ", root->data);
	InOrder(root->right);
}
后序遍历

先遍历左子树,再遍历右子树,最后遍历根节点

左右根

NULL->NULL->D->NULL->B->NULL->NULL->E->NULL->NULL->F->C->A

c 复制代码
//后序遍历--左右根
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%c ", root->data);
}

节点个数

节点个数 = 1(根节点)+ 左子树节点个数 + 右子树节点个数

c 复制代码
// ⼆叉树结点个数 
int BinaryTreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	//节点个数 = 1(根节点)+ 左子树节点个数 + 右子树节点个数
	return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}

叶子节点个数

叶子节点个数 = 左子树叶子节点个数 + 右子树叶子节点个数

c 复制代码
//⼆叉树叶⼦结点个数 
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层结点个数

当k == 1,直接在当前节点返回,

当k != 1,继续向下一层递归,k-1

c 复制代码
//⼆叉树第k层结点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}
	if (k == 1)
	{
		return 1;
	}
	return BinaryTreeLevelKSize(root->left, k - 1) 
		+ BinaryTreeLevelKSize(root->right, k - 1);
}

⼆叉树的深度/⾼度

c 复制代码
//⼆叉树的深度/⾼度
int BinaryTreeDepth(BTNode* root)
{
	if (root == 0)
	{
		return 0;
	}
	//高度 = max(左子树,右子树)+ 1
	return 1 + max(BinaryTreeDepth(root->left), BinaryTreeDepth(root->right));
}

查找值为X的节点

c 复制代码
//⼆叉树查找值为x的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->data == x)
	{
		return root;
	}
	BTNode* leftFind = BinaryTreeFind(root->left, x);
	if (leftFind)
	{
		return leftFind;
	}
	BTNode* rightFind = BinaryTreeFind(root->right, x);
	if (rightFind)
	{
		return rightFind;
	}
	return NULL;
}

二叉树的销毁

使用后序遍历

c 复制代码
//⼆叉树销毁
void BinaryTreeDestory(BTNode** root)
{
	if (*root == NULL)
	{
		return;
	}
	BinaryTreeDestory(&((*root)->left));
	BinaryTreeDestory(&((*root)->right));
	free(*root);
	*root = NULL;
}

层序遍历

按照层次依次遍历(从上到下,从左到右)

广度优先遍历

思路:

使用队列,根节点入队,循环判断队列是否为空,不为空取队头,将队头结点左右孩子入队(非空)

c 复制代码
//层序遍历
void LevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		//取队头,出队,将左右孩子(非空)入队
		BTNode* top = QueueFront(&q);
		QueuePop(&q);
		printf("%c ", top->data);
		if (top->left)
		{
			QueuePush(&q,top->left);
		}
		if (top->right)
		{
			QueuePush(&q, top->right);
		}
	}
	QueueDestory(&q);
}

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

c 复制代码
// 判断⼆叉树是否是完全⼆叉树
bool BinaryTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		//取队头,出队,将左右孩子(非空)入队
		BTNode* top = QueueFront(&q);
		QueuePop(&q);
		if (top == NULL)
		{
			break;
		}
		//入队
		QueuePush(&q, top->left);
		QueuePush(&q, top->right);
	}
	//如果存在非空结点,是非完全二叉树
	while (!QueueEmpty(&q))
	{
		BTNode* top = QueueFront(&q);
		QueuePop(&q);
		if (top != NULL)
		{
			QueueDestory(&q);
			return false;
		}
	}
	QueueDestory(&q);
	return true;
}
相关推荐
UIU1146 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
论文复现现场6 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
ZhengEnCi6 小时前
用 AI 写代码为什么拼到最后还是拼人:算力瓶颈与领域专家提示词的本质差异
算法·架构
秋天的怀念_David7 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
碧海银沙音频科技研究院8 小时前
在PC电脑上用Whisper→Marian算法实现离线语音翻译功能
算法·whisper
niyongsheng8 小时前
3D 装箱算法工程化:数据结构、放置启发式与支撑规则
数据结构·算法·rust
叉烧滑蛋11 小时前
B站台湾大学郭彦甫|MATLAB 学习笔记|04 变量与档案存取
数据结构
j7~11 小时前
【穷举、深搜与回溯算法】一棵决策树讲透全排列与子集
数据结构·c++·算法·leetcode·回溯·递归
傅科摆 _ py12 小时前
DP,贪心,堆和栈,二分力扣复习
开发语言·python·算法
Shaoshing13 小时前
LeetCode100 42.接雨水
java·算法·leetcode