文章目录
一、小状元课上习题
1、二叉树
1.1 求树的高数/深度
思路
思路:
设置变量lh、rh分别用来记录左右子树的深度/高度
1、判断当前树根是否为空,为空则返回0
2、不为空,则递归调用左子树和右子树
3、递归结束后,如果左子树深度比较深则lh+1,否则rh+1
代码
int DepthOfTree(BTNode *bt)
{
int lh, rh; // lh、rh分别用来记录左右子树的深度/高度
if (!bt) return 0; // 判断当前树根是否为空,为空则返回0
lh = DepthOfTree(bt->lChild); // 不为空,则递归调用左子树和右子树
rh = DepthOfTree(bt->rChild);
return lh > rh ? lh + 1 : rh + 1; // 如果左子树深度比较深则lh+1,否则rh+1
}
1.2 求二叉树叶子结点的个数
思路
思路:
lleaf,rleaf用来存储左右子树的叶子结点个数
1、如果当前树根为空,则返回0
2、如果当前树根的左右孩子均为空,则返回1
3、如果当前树根的左孩子或右孩子不为空,则递归调用左右孩子
4、把左右子树的叶子结点个数相加,并返回
代码
1、版本一:设置变量
int leafSize(BTNode *bt)
{
int lleaf, rleaf;
if (!bt) return 0; // 如果当前树根为空,则返回0
if (!bt->lChild && !bt->rChild) // 如果当前树根的左右孩子均为空,则返回1
return 1;
if (bt->lChild) // 如果当前树根的左孩子或右孩子不为空,则递归调用左右孩子
lleaf = leafSize(bt->lChild);
if (bt->rChild)
rleaf = leafSize(bt->rChild);
return lleaf + rleaf; // 把左右子树的叶子结点个数相加,并返回
}
2、版本二:不设置变量(更简洁)
int leafSize(BTNode *bt)
{
if (!bt) // 如果当前树根为空,则返回0
return 0;
else if (!bt->lChild && !bt->rChild) // 如果当前树根的左右孩子均为空,则返回1
return 1;
// 如果当前树根的左孩子或右孩子不为空,则递归调用左右孩子
else
return leafSize(bt->lChild) + leafSize(bt->rChild); // 把左右子树的叶子结点个数相加,并返回
}
1.3 求二叉树结点的个数
思路
1、如果当前树根为空,则返回0
2、否则递归计算左子树和右子树的结点个数+1(+1原因是当前根结点的个数是1)
代码
int TreeSize(BTNode *bt)
{
if (!bt) return 0; // 如果当前树根为空,则返回0
else // 否则递归计算左子树和右子树的结点个数+1(+1原因是当前根结点的个数是1)
return TreeSize(bt->lChild) + TreeSize(bt->rChild) + 1;
}
1.4 求二叉树度为1的结点个数
思路
1、如果当前树根为空,则返回0
2、如果当前树根的左子树不为空,右子树为空,或者如果当前树根的右子树不为空,左子树为空(即判断当前树根是否是度为1的结点)
则返回左子树度为1的结点个数 + 右子树度为1的结点个数 + 1(+1是因为根结点也是度为1的结点)
3、如果当前树根不是度为1的结点,则返回左子树度为1的结点个数 + 右子树度为1的结点个数
代码
int DegreeOne(BTNode *bt)
{
if (!bt)// 如果当前树根为空,则返回0
return 0;
/*
如果当前树根的左子树不为空,右子树为空,或者如果当前树根的右子树不为空,左子树为空(即判断当前树根是否是度为1的结点)
则返回左子树度为1的结点个数 + 右子树度为1的结点个数 + 1( + 1是因为根结点也是度为1的结点)
*/
if ((!bt->lChild && bt->rChild) || (bt->lChild && !bt->rChild))
return DegreeOne(bt->lChild) + DegreeOne(bt->rChild) + 1;
else // 如果当前树根不是度为1的结点,则返回左子树度为1的结点个数 + 右子树度为1的结点个数
return DegreeOne(bt->lChild) + DegreeOne(bt->rChild);
}
1.5 求二叉树度为2的结点个数
思路
1、如果当前树根为空,则返回0
2、如果当前树根的左孩子和右孩子都不为空(即树根为度为2的结点),则返回左子树度为2的结点+右子树度为2的结点+1
否则(树根不是度为2的结点),返回左子树度为2的结点+右子树度为2的结点
代码
int DegreeTwo(BTNode *bt)
{
if (!bt) // 如果当前树根为空,则返回0
return 0;
// 如果当前树根的左孩子和右孩子都不为空(即树根为度为2的结点),则返回左子树度为2的结点+右子树度为2的结点+1
if (bt->lChild && bt->rChild)
return DegreeTwo(bt->lChild) + DegreeTwo(bt->rChild) + 1;
// 否则(树根不是度为2的结点),返回左子树度为2的结点+右子树度为2的结点
else
return DegreeTwo(bt->lChild) + DegreeTwo(bt->rChild);
}
1.6 交换二叉树的左右子树
思路
思路:
1、如果当前树根为空,则返回false
2、设置一个临时结点tmp,先把左子树赋给tmp,再把右子树赋给左子树,再把tmp赋给右子树(类似于两个变量的交换)
3、递归交换左右子树
代码
bool exchange(BTNode *bt)
{
if (!bt)// 如果当前树根为空,则返回false
return false;
// 设置一个临时结点tmp,先把左子树赋给tmp,再把右子树赋给左子树,再把tmp赋给右子树(类似于两个变量的交换)
BTNode *tmp = bt->lChild;
bt->lChild = bt->rChild;
bt->rChild = tmp;
// 递归交换左右子树
exchange(bt->lChild);
exchange(bt->rChild);
}