树(上半期)

建树

struct tr{
    char x;
    tr*lc,*rc;
};
#define nu NULL
// 建树
tr* create()
{
    tr*t ;
    char x;cin>>x;
    if(x=='#')
    {
        t=nu;
    }else{
        t=new tr;
        t->x=x;
        t->lc=nu;t->rc=nu;
        t->lc=create();t->rc=create();
    }
    return t;
}

题目

统计树的深度

流程:

1.建树

2.统计深度

// 建树操作
/*
统计二叉树的深度(t:代表当前这个节点)
    当前节点存在:就去找它左右儿子最大的深度+当前这个节点(1),就是max(depth(t->lc),depth(t->rc))+1;
    当前节点不存在:则它的depth就为0了
*/
int depth(tr *t)
{
    return t?(max( depth(t->lc) , depth(t->rc) ))+1
    :0;
}
int main()
{
    tr*t=nu;
    t=create();
    cout<<depth(t)<<endl;//统计深度
}

统计树的宽度

// 建树
/*
统计宽度(t代表当前节点,cur代表当前是哪一层的)=>统计当前层有多少个节点,找到max
cnt数组:当前找到的在第cur层有多少个节点
mx:最大,也就是我们的res
    当前节点存在:那么我们这一层又找到了一个点,于是cnt[cur]++,之后我们去找他的左右儿子,分别对应的都是下一层了,所以是cur+1
*/
int mx=-1,cnt[10010];
void width(tr*t,int cur)
{
    if(t)
    {
        cnt[cur]++;
        mx=max(mx,cnt[cur]);
        width(t->lc,cur+1);
        width(t->rc,cur+1);
    }
}
int main()
{
    tr*t=nu;
    t=create();
    width(t,1);//统计宽度
    cout<<mx<<endl;
}

找叶子节点

// 建树
/*
统计叶节点个数(t为当前节点),cnt记录叶子节点
    1.当前节点不存在:返回
    2.当前节点无左右儿子(叶子节点):cnt++;
    3.当前节点有儿子节点:递归下去找他的叶子节点。
*/
int cnt=0;
void leaf(tr*t)
{
    if(!t) return;
    if(!t->lc&&!t->rc){cnt++;return;}
    else{
        leaf(t->lc);
        leaf(t->rc);
    }
}
int main()
{
    tr*t=nu;
    t=create();
    leaf(t);
    cout<<cnt;
}

统计二叉树的度为2的结点个数

/*
统计二叉树的度为2的结点个数
    1.当前点为空,返回
    2.有左右儿子,此时该点的度为2:数量+1
    递归下去
    ※注意:当有左右儿子时,我们仍然要递归下去,因为它的儿子节点可能也存在满足题意的情况。
*/
int ans=0;
void cnt(tr*t)
{
    if(!t) return ;
    if(t->lc&&t->rc)ans++;
    
    cnt(t->lc);
    cnt(t->rc);
    
}
int main()
{
    tr*t=nu;
    t=create();
    cnt(t);
    cout<<ans;
}

统计二叉树度为1的结点的个数

// 建树
/*
统计的二叉树的度为1的结点个数
    1.当前节点为空,回溯
    2.只有左儿子或只有右儿子,ans++;
    递归下去
*/
int ans=0;
void cnt(tr*t)
{
    if(!t) return;
    if((t->lc&&!t->rc)||(t->rc&&!t->lc)) ans++;
    cnt(t->lc);
    cnt(t->rc);
}
int main()
{
    tr*t=nu;
    t=create();
    cnt(t);
    cout<<ans;
}

统计二叉树中的空链域个数

// 建树
/*
统计二叉树中的空链域个数
    1.当前节点为空,此时为空链域,ans++,回溯;
    2.不为空则继续找当前节点的儿子节点
*/
int ans=0;
void cnt(tr*t)
{
    if(!t) {ans++;return;}
    cnt(t->lc);
    cnt(t->rc);
}
int main()
{
    tr*t=nu;
    t=create();
    cnt(t);
    cout<<ans;
}

二叉树的遍历

二叉树相关

/*
先序遍历
    当前,左,右
*/
void cnt(tr*t)
{
    if(!t) return;
    cout<<t->x;
    cnt(t->lc);
    cnt(t->rc);
}
/*
中序遍历
   左,当前,右
*/
void cnt(tr*t)
{
    if(!t) return;
    cnt(t->lc);
    cout<<t->x;
    cnt(t->rc);
}
/*
后序遍历
    左,右,当前
*/
void cnt(tr*t)
{
    if(!t) return;
    cnt(t->lc);
    cnt(t->rc);
    cout<<t->x;
}
原文地址:https://www.cnblogs.com/Calculus9/p/14668167.html