二叉树的递归实现

二叉树的二叉链表结构:

typedef struct BiTNode
{
    ElemType data;//数据域
    struct BiTNode *lchild, *rchild;//两个指针域,分别指向左子树和右子树
}BiTNode,*BiTree;

创建一个二叉树:每生成一个新结点,如果该结点为空,就不用再递归生成左右子树结点。

Status CreateBiTree(BiTree &t)
{
    ElemType ch;
    cin >> ch;
    if (ch == '#')
        t = NULL;//此树为空树,不再对它递归生成左右子树结点
    else
    {
        t = (BiTree)malloc(sizeof(BiTNode));
        if (!t)
            exit(OVERFLOW);
        t->data = ch;//对结点元素赋值
        CreateBiTree(t->lchild);//递归生成左子树
        CreateBiTree(t->rchild);//递归生成右子树
    }
    return OK;
}

先(根)序遍历:访问根结点,先序遍历左子树,先序遍历右子树
中(根)序遍历:中序遍历左子树,访问根结点,中序遍历右子树
后(根)序遍历:后序遍历左子树,后序遍历右子树,访问根结点

/*先序遍历*/
void PreOrderTraverse(BiTree t, Status(*visit)(ElemType))
{
    if (t)
    {
        visit(t->data);//输出结点元素
        PreOrderTraverse(t->lchild, visit);//先序遍历左子树
        PreOrderTraverse(t->rchild, visit);//先序遍历右子树
    }
}
/*中序遍历*/
void InOrderTraverse(BiTree t, Status(*visit)(ElemType))
{
    if (t)
    {
        InOrderTraverse(t->lchild, visit);//中序遍历左子树
        visit(t->data);//输出结点元素
        InOrderTraverse(t->rchild, visit);//中序遍历右子树
    }
}
/*后序遍历*/
void PostOrderTraverse(BiTree t, Status(*visit)(ElemType))
{
    if (t)
    {
        PostOrderTraverse(t->lchild, visit);//后序遍历左子树
        PostOrderTraverse(t->rchild, visit);//后序遍历右子树
        visit(t->data);//输出结点元素
    }
}
/*输出函数*/
Status print(ElemType e)
{
    cout << e;
    return OK;
}

深度递归求法:分别通过递归调用获得某结点的左右子树最大深度,该结点的深度既为左右子树最大深度+1,类推根结点可以得到树的深度大小。

int depth(BiTree t)
{
    int depthl, depthr;
    if (!t)
        return 0;
    depthl = depth(t->lchild);//递归遍历左子树,求得所在结点左子树的最大深度
    depthr = depth(t->rchild);//递归遍历右子树,求得所在结点右子树的最大深度
    return (depthl > depthr ? depthl : depthr) + 1;//返回该结点左右子树最大深度值+1
}

判断俩个二叉树是否相同:先判断所在结点是否为空,元素的值是否相同,然后先序遍历左右子树

Status Equal(BiTree t1, BiTree t2)
{
    if (t1 == NULL&&t2 == NULL)//如果两个结点都为空,则相同
        return TRUE;
    else if (t1 == NULL || t2 == NULL)//如果一个为空,另一个不为空,则不同
        return FALSE;
    else
    {
        if (t1->data == t2->data)//如果两个结点的元素相同
            if (Equal(t1->lchild, t2->lchild))//判断两个结点的左子树
                if (Equal(t1->lchild, t2->rchild))//判断两个结点的右子树
                    return TRUE;
        return FALSE;
    }
}

删除结点及其子孙结点:先序遍历寻找元素对应结点,后序遍历释放子孙结点,对应结点指向空域

void DelSubTree(BiTree t)
{
    if (t)//结点不空
    {
        DelSubTree(t->lchild);//遍历该结点左子树
        DelSubTree(t->rchild);//遍历该结点右子树
        free(t);//释放结点空间
    }
}

void DelTree(BiTree &t, ElemType x)
{
    if (t)
    {
        if (t->data == x)//找到想要删除的结点
        {
            DelSubTree(t);//释放该结点和其子孙结点的空间
            t = NULL;//该结点指NULL
        }
        else
        {
            DelTree(t->lchild,x);//遍历左子树寻找对应结点
            DelTree(t->rchild,x);//遍历右子树寻找对应结点
        }
    }
}

返回二叉树先序序列第k个结点的值: 先序遍历寻找该结点,然后输出元素

BiTree count_k(BiTree t, int &k)
{
    BiTree p;
    if (!t || k <= 0)//结点为空或者没有该序号,输出空
        return NULL;
    k--;
    if (k == 0)//k==0,则为该结点
        return t;
    if (p = count_k(t->lchild, k))//遍历左子树寻找该结点
        return p;
    else//遍历右子树寻找该结点
        return count_k(t->rchild, k);
}

Status Loc_k(BiTree t, int k, ElemType &e)
{
    BiTree p;
    p = count_k(t, k);
    if (p)
    {
        e = p->data;
        return OK;
    }
    else
        return ERROR;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值