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

实现链式结构的二叉树

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

其结构如下:

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;
}
相关推荐
猎板PCB厚铜专家大族8 分钟前
高频 PCB 技术发展趋势与应用解析
人工智能·算法·设计规范
dying_man19 分钟前
LeetCode--24.两两交换链表中的结点
算法·leetcode
yours_Gabriel19 分钟前
【力扣】2434.使用机器人打印字典序最小的字符串
算法·leetcode·贪心算法
草莓熊Lotso1 小时前
【数据结构初阶】--算法复杂度的深度解析
c语言·开发语言·数据结构·经验分享·笔记·其他·算法
KyollBM1 小时前
【CF】Day75——CF (Div. 2) B (数学 + 贪心) + CF 882 (Div. 2) C (01Trie | 区间最大异或和)
c语言·c++·算法
CV点灯大师1 小时前
C++算法训练营 Day10 栈与队列(1)
c++·redis·算法
GGBondlctrl2 小时前
【leetcode】递归,回溯思想 + 巧妙解法-解决“N皇后”,以及“解数独”题目
算法·leetcode·n皇后·有效的数独·解数独·映射思想·数学思想
武子康2 小时前
大数据-276 Spark MLib - 基础介绍 机器学习算法 Bagging和Boosting区别 GBDT梯度提升树
大数据·人工智能·算法·机器学习·语言模型·spark-ml·boosting
武子康2 小时前
大数据-277 Spark MLib - 基础介绍 机器学习算法 Gradient Boosting GBDT算法原理 高效实现
大数据·人工智能·算法·机器学习·ai·spark-ml·boosting