例题:设二叉树的存储结构为二叉链表,编写有关二叉树的递归算法:
(1)统计二叉树中度为1的结点个数;
(2)统计二叉树中度为2的结点个数;
(3)统计二叉树中度为0的结点个数;
(4)统计二叉树的高度;
(5)统计二叉树的宽度;
(6)从二叉树中删去所有叶节点;
(7)计算指定结点*p所在的层次;
(8)计算二叉树中各节点中的最大元素的值;
(9)交换二叉树中每个结点的两个子女;
(10)以先序次序输出一颗二叉树中所有结点的数据值及结点所在层次。
文章目录
(1)统计二叉树中度为1的结点个数
void CountNode1(BiTree T)
{
static int num=0;//在函数内部定义,这个变量只初始化一次
if (T == NULL)
return;
if ((T->lchild && !T->rchild) || (!T->lchild && T->rchild))//左右子树只有一个非空
num++;
CountNode1(T->lchild);
CountNode1(T->rchild);
}
(2)统计二叉树中度为2的结点个数
void CountNode2(BiTree T)
{
static int num=0;//在函数内部定义,这个变量只初始化一次
if (T == NULL)
return;
if (T->lchild && T->rchild))//左右子树都非空
num++;
CountNode2(T->lchild);
CountNode2(T->rchild);
}
(3)统计二叉树中度为0的结点个数
void CountNode0(BiTree T)
{
static int num=0;//在函数内部定义,这个变量只初始化一次
if (T == NULL)
return;
if (!T->lchild && !T->rchild))//左右子树都为空
num++;
CountNode0(T->lchild);
CountNode0(T->rchild);
(4)统计二叉树的高度
int Height(BiTree T)
{
if (T == NULL)
return 0;
return Max(Height(T->lchild), Height(T->rchild)) + 1;
}
(5)统计二叉树的宽度
// 求解树的高度
int getHeight(BiTree T) {
if (T == NULL) {
return 0;
}
int leftHeight = getHeight(T->left);
int rightHeight = getHeight(T->right);
return 1 + max(leftHeight, rightHeight);
}
// 求解每层的节点数
int getWidthAtLevel(BiTree T, int level) {//level是树的层数,层数是由低到高增大
if (T==NULL) {
return 0;
}
if (level == 1) {//到达叶子结点
return 1;
}
else if (level > 1) {
return getWidthAtLevel(T->left, level - 1) + getWidthAtLevel(T->right, level - 1);
}
return 0;
}
// 求解二叉树的宽度
int getTreeWidth(BiTree T) {
int maxWidth = 0;
int height = getHeight(T);
for (int i = 1; i <= height; i++) {//最宽的那层为树的宽度
int levelWidth = 0;
getWidthOfLevel(T, i, &levelWidth);
if (levelWidth > maxWidth) {
maxWidth = levelWidth;
}
}
return maxWidth;
}
(6)从二叉树中删去所有叶节点
要使用递归算法删除二叉树中的所有叶节点(叶子结点是没有子节点的节点),可以按照以下步骤进行:
1.如果二叉树为空(即根节点为NULL),则不需要执行任何操作。
2.否则,递归地调用删除叶节点的函数,首先删除左子树中的叶节点,然后删除右子树中的叶节点。
3.在递归过程中,检查当前节点是否为叶节点(即左右子节点都为空)。如果是叶节点,则释放当前节点的内存并将其设置为NULL。
// 递归函数来删除叶节点
void deleteLeaves(BiTree &T) {
if (T == NULL) {
return;
}
// 递归地删除左子树和右子树的叶节点
deleteLeaves(root->left);
deleteLeaves(root->right);
// 检查当前节点是否为叶节点
if (root->left == NULL && root->right == NULL) {
free(T);
T = NULL;
}
}
(7)计算指定结点*p所在的层次
1.如果二叉树为空(即根节点为 NULL),或者 p 为NULL,则返回 0 或其他适当的值,表示未找到。
2.如果根节点为 p,则返回 1,表示根节点所在的层次为 1。
3.否则,递归地计算 p 在左子树和右子树中的层次,然后取较大的层次值,再加 1,以表示 p 在当前树中的层次。
// 递归函数来计算指定节点的层次
int findNodeLevel(BiTree T, BiNode* p, int level) {//level初始值为1
if (T == NULL) {
return 0; // 如果树为空或未找到节点,返回0表示未找到
}
if (T == p) {
return level; // 找到了目标节点,返回当前层次
}
// 递归在左子树和右子树中查找
int leftLevel = findNodeLevel(T->left, p, level + 1);
if (leftLevel != 0) {
return leftLevel; // 在左子树中找到了,返回结果
}
int rightLevel = findNodeLevel(root->right, p, level + 1);
return rightLevel; // 返回左子树和右子树中的非零结果
}
(8)计算二叉树中各节点中的最大元素的值
int findMaxInSubtree(BiTree T) {
if (T == NULL) {
return INT_MIN; // 对于空节点,返回一个较小的值
}
int leftMax = findMaxInSubtree(root->left);
int rightMax = findMaxInSubtree(root->right);
// 返回左子树、右子树和当前节点的最大值
return max(max(leftMax, rightMax), root->data);
}
(9)交换二叉树中每个结点的两个子女
// 递归函数来交换二叉树中每个节点的左右子树
void swapChildren(BiTree T) {
if (T == NULL) {
return;
}
// 递归交换左右子树
BiNode* temp = T->left;
T->left = T->right;
T->right = temp;
swapChildren(T->left);
swapChildren(T->right);
}
(10)以先序次序输出一颗二叉树中所有结点的数据值及结点所在层次。
// 递归函数来以先序遍历方式输出二叉树节点的数据值和层次
void preOrderTraversalWithLevel(BiTree T, int level) {//level初始值为1
if (T == NULL) {
return;
}
// 输出节点数据值和层次
cout << "Node: " << T->data << ", Level: " << level << endl;
// 递归遍历左子树和右子树,层次加一
preOrderTraversalWithLevel(T->left, level + 1);
preOrderTraversalWithLevel(T->right, level + 1);
}