暴力数据结构之二叉树(初阶)

递归是一种很重要的思想,他可以帮助我们将大问题细分为许多个小问题,从而拆解问题,使得问题简单化,本篇博客主要利用的就是递归的思想,将整棵树的问题拆解为许多个根节点与左右子树的简单问题。

1. 二叉树遍历

总体核心思路:核心逻辑为递归调用,即分治思想,将问题不断拆解,从初始根节点与左右子树依次向下分解,直到叶子结点不可再分。

1.1 前序遍历

前序遍历主要是以 先根节点 再左子树 再右子树为逻辑遍历, 以例图为例

前序遍历后为:A B D NULL NULL NULL C NULL E NULL NULL

cs 复制代码
BTNode* BuyNode(int x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	if (node == NULL)
	{
		perror("malloc fail");
		return NULL;
	}

	node->data = x;
	node->left = NULL;
	node->right = NULL;

	return node;
}
void PrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}

	printf("%d ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);
}
1.2 中序遍历

核心逻辑:以左子树 根节点 右子树的顺序遍历

中序遍历后结果为:NULL D NULL B NULL A NULL C NULL E NULL

cs 复制代码
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}

	InOrder(root->left);
	printf("%d ", root->data);
	InOrder(root->right);
}
1.3 后序遍历

核心逻辑:以左子树 右子树 根节点 的顺序遍历

中序遍历后结果为:NULL NULL D NULL B NULL NULL NULL E C A

cs 复制代码
void BehendOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}

	BehendOrder(root->left);
	BehendOrder(root->right);
	printf("%d ", root->data);
}

2. 树的计算

2.1 计算全部节点个数

计算全部节点就是遍历整棵树后计算所有节点即可,不递归的方法就是使用全局变量或者传一个指针参数,这二者均有局限,所以主要介绍递归。

非递归:

cs 复制代码
int size = 0;
int TreeSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	else
		++size;

	TreeSize(root->left);
	TreeSize(root->right);

	return size;
}

void TreeSize(BTNode* root, int* psize)
{
	if (root == NULL)
		return 0;
	else
		++(*psize);

	TreeSize(root->left, psize);
	TreeSize(root->right, psize);
}

递归:依旧是将大问题分解为小问题,然后直到无法分解为止,将遍历整棵树看做遍历一个根节点与左子树和右子树,逐层拆解。

cs 复制代码
int TreeSize(BTNode* root)
{
	return root == NULL ? 0 :
		TreeSize(root->left) + TreeSize(root->right) + 1;
}
2.2 计算叶子节点个数

首先空树没有叶子节点,直接返回返回0,是叶子结点返回1,不是叶子结点就递归返回他的左子树与右子树,逐层拆解到叶子节点。

cs 复制代码
int TreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;

	if (root->left == NULL && root->right == NULL)
		return 1;

	return TreeLeafSize(root->left)
		+ TreeLeafSize(root->right);
}
2.3 计算树的高度

这里保存左右子树的高度,防止递归导致栈溢出。即分别求左子树与右子树的告诉,返回较大的值加一。

但是可以使用fmax来取出二者较大值,也是一种新思路。

cs 复制代码
 有效率问题
int TreeHeight(BTNode* root)
{
	if (root == NULL)
		return 0;

	return TreeHeight(root->left) > TreeHeight(root->right) ?
		TreeHeight(root->left) + 1 : TreeHeight(root->right) + 1;
}

int fmax(int x, int y)
{
	return x > y ? x : y;
}

int TreeHeight(BTNode* root)
{
	if (root == NULL)
		return 0;

	return fmax(TreeHeight(root->left), TreeHeight(root->right)) + 1;
}
cs 复制代码
int TreeHeight(BTNode* root)
{
	if (root == NULL)
		return 0;

	int leftHeight = TreeHeight(root->left);
	int rightHeight = TreeHeight(root->right);

	return leftHeight > rightHeight ?
		leftHeight + 1 : rightHeight + 1;
}
2.4 计算第K层的节点数

递归:空树返回空,第零层即只有根节点返回1,其余的拆解为左子树与右子树的问题,依次递归。

cs 复制代码
int KTreeSize(BTNode* root, int k)
{
	if (root == NULL)
		return 0;
	if(k == 0)
		return 1;
	return KTreeSize(root->left, k - 1) + KTreeSize(root->right, k - 1);
}

3. Leetcode 练习

965.单值二叉树

思路解析: 判断是否为单值二叉树就是判断所有节点的值是否相同。但是依次遍历判断有些麻烦,所以这里可以使用反证法,即只要找到不符合的节点就直接返回false,并结合递归的方法,将大问题分解为小问题。

具体解析:首先空树符合单值二叉树,直接返回true,其次判断左子树,先判断是否存在,之后判断其节点对应的值是否与根节点对应的值相同,右子树同理,最后返回递归的值。

cs 复制代码
bool isUnivalTree(struct TreeNode* root)
{
    if(root == NULL)
       return true;

    if(root->left && root->left->val != root->val)
       return false;

    if(root->right && root->right->val != root->val)
       return false;

    return isUnivalTree(root->left) && isUnivalTree(root->right);
}
相关推荐
墨染点香3 分钟前
LeetCode 刷题【124. 二叉树中的最大路径和、125. 验证回文串】
算法·leetcode·职场和发展
Camel卡蒙4 分钟前
红黑树详细介绍(五大规则、保持平衡操作、Java实现)
java·开发语言·算法
AhriProGramming15 分钟前
Flask-SQLAlchemy精读-双语精选文章
python·算法·flask
孤廖30 分钟前
吃透 C++ 栈和队列:stack/queue/priority_queue 用法 + 模拟 + STL 标准实现对比
java·开发语言·数据结构·c++·人工智能·深度学习·算法
BanyeBirth1 小时前
C++动态规划——LIS(最长不下降子序列)
算法·动态规划
小龙报1 小时前
《算法通关指南---C++编程篇(3)》
开发语言·c++·算法·visualstudio·学习方法·visual studio
凤山老林1 小时前
排序算法:详解插入排序
java·开发语言·后端·算法·排序算法
豆沙沙包?1 小时前
2025年--Lc197-077. 排序链表(链表,尾插法)--Java版
java·数据结构·链表
知星小度S2 小时前
算法训练之多源BFS
算法·宽度优先
2201_758875442 小时前
LeetCode:19. 删除链表的倒数第 N 个结点
算法·leetcode·链表