例题:设二叉树的存储结构为二叉链表,编写有关二叉树的递归算法

文章详细介绍了如何使用递归方法在二叉树中进行各种操作,包括统计不同度的节点数、计算树的高度和宽度、删除叶节点、查找节点层次、求最大元素、交换节点子树以及先序遍历节点数据和层次。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

例题:设二叉树的存储结构为二叉链表,编写有关二叉树的递归算法:

(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);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值