当前位置: 首页 > article >正文

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

实现链式结构的二叉树

    • 实现链式结构的二叉树
      • 遍历
        • 前序遍历
        • 中序遍历
        • 后序遍历
      • 节点个数
      • 叶子节点个数
      • ⼆叉树第k层结点个数
      • ⼆叉树的深度/⾼度
      • 查找值为X的节点
      • 二叉树的销毁
    • 层序遍历
    • 判断二叉树是否为完全二叉树

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

其结构如下:

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

遍历

前中后序遍历

前序遍历

也叫先根遍历

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

左右根

image-20250122120904177 image-20250122121456060

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

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

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

左根右

image-20250122120908431 image-20250122122358193

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

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

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

左右根

image-20250122120912308 image-20250122123010493

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

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

节点个数

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

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

叶子节点个数

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

//⼆叉树叶⼦结点个数 
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

//⼆叉树第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);
}

⼆叉树的深度/⾼度

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

查找值为X的节点

//⼆叉树查找值为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;
}

二叉树的销毁

使用后序遍历

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

层序遍历

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

广度优先遍历

image-20250218160303782

思路:

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

//层序遍历
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);
}

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

// 判断⼆叉树是否是完全⼆叉树
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;
}

http://www.kler.cn/a/569768.html

相关文章:

  • vcredist_x64 资源文件分享
  • React(11)路由demo
  • IDEA相关配置
  • LeetCode-154. 寻找旋转排序数组中的最小值 II
  • go类(结构体)和对象
  • 派可数据BI接入DeepSeek,开启智能数据分析新纪元
  • GPT-4.5
  • 力扣785. 判断二分图
  • 黑龙江省地标-DB31/T 862-2021 “一网通办”政务服务中心建设和运行规范
  • js基础二
  • 我通过AI编程完成了第一个实用程序
  • 避免 Git 文件名大小写出错
  • CAN总线通信协议学习2——数据链路层之帧格式
  • 服务器项目部署环境配置(windows10)
  • 【大模型系列篇】DeepSeek开源周,解锁AI黑科技
  • Mac OS Homebrew更换国内镜像源(中科大;阿里;清华)
  • keil主题(vscode风格)
  • leetcode 59. 螺旋矩阵 II 中等
  • C# 中 Array、ArrayList 和 List 的比较
  • 【前端基础】3、HTML的常用元素(h、p、img、a、iframe、div、span)、不常用元素(strong、i、code、br)