二叉树的建立与遍历小结

21 篇文章 0 订阅
4 篇文章 0 订阅

好久前就学完二叉树了,不过不善总结,到现在才温习一遍,感觉全是模板啊,有点难的就是那个树的同构~。

首先我们可以根据给出的字串建立起二叉树(如","为空节点特判),我们还可以根据(先序+中序)或者 (中序+后序)得到唯一的二叉树,当然了(先序+后序)得到可能的二叉树种数也是题目,不过我还没遇到,这里就不写了。建立好二叉树后我们可以先序(根左右),中序(左根右),后序(左右根),层序,来遍历二叉树,层次遍历我们用队列来实现即可,层次遍历中遇到的叶子节点特判输出即可(如果这是题目的话),获得叶子节点的数目的话,找左右全为空的节点++即可。

#include<bits/stdc++.h>
using namespace std;
struct node
{
    node *l,*r;
    char data;
};
char a[100];
int top=-1,sum;
node *create1()
{
    node *root;
    root=new node;
    top++;
    if(a[top]==',')  //","代表空节点
        return NULL;
    else             //树根节点,左右子树的建立
    {
        root->data=a[top];
        root->l=create1();
        root->r=create1();
    }
    return root;  //return 的是一个树
}
node *create2(char *previous,char *middle,int len)//先序+中序==二叉树
{
    if(len<=0)
        return NULL;  //终止条件很重要
    node *root;
    root=new node;
    root->data=previous[0];
    int i;
    for(i=0;i<len;i++)
    {
        if(middle[i]==previous[0])//找到中序遍历中根节点的分界
            break;
    }
    root->l=create2(previous+1,middle,i);//画个图很好理解
    root->r=create2(previous+i+1,middle+i+1,len-1-i);
    return root;
}
node *create3(char *middle,char *finall,int len)//中序+后序==二叉树
{
    if(len<=0)
        return NULL;
    node *root;
    root=new node;
    root->data=finall[len-1];
    int i;
    for(i=0;i<len;i++)
    {
        if(middle[i]==finall[len-1])
            break;
    }
    root->l=create3(middle,finall,i);
    root->r=create3(middle+i+1,finall+i,len-1-i);
    return root;
}
void previousshow(node *root) //先序根左右
{
    if(root)
    {
        cout<<root->data;
        previousshow(root->l);
        previousshow(root->r);
    }
}
void middleshow(node *root)//中序左根右
{
    if(root)
    {
        middleshow(root->l);
        cout<<root->data;
        middleshow(root->r);
    }
}
void finallshow(node *root) //后序左右根
{
    if(root)
    {
        finallshow(root->l);
        finallshow(root->r);
        cout<<root->data;
    }
}
void layershow(node *root)  //运用队列实现的层次遍历
{
    queue<node*>que;//注意这里是node*,坑死我了
    if(root)        //一定要特判,不然会RE
    {
        que.push(root);
        cout<<que.front()->data;
    }
    while(que.size())
    {
        node *root=que.front(); //常用手段
        que.pop();
        if(root->l)  //依次找左右儿子输出即可
        {
            cout<<root->l->data;
            que.push(root->l);
        }
        if(root->r)
        {
            cout<<root->r->data;
            que.push(root->r);
        }
    }
}
void layershow(node *root) //运用层次遍历输出叶子节点
{
    queue<node*>que;//注意这里是node*,坑死我了
    if(root)        //一定要特判,不然会RE
    {
        que.push(root);
    }
    while(que.size())
    {
        node *root=que.front(); //常用手段
        if(root->l==NULL&&root->r==NULL) //输出叶子节点
            cout<<root->data;
        que.pop();
        if(root->l)  //依次找左右儿子输出即可
        {
            que.push(root->l);
        }
        if(root->r)
        {
            que.push(root->r);
        }
    }
}
int getdepth(node *root) //求深度和高度,不过其还是有点差别的
{
    int depth=0;
    if(root)
        depth=max(getdepth(root->l),getdepth(root->r))+1;
    return depth;
}
int getleafsum(node *root)  //获得叶子节点的个数
{
    if(root)
    {
        if(root->l==NULL&&root->r==NULL) //左右全为空的节点为叶子节点
            sum++;
        else
        {
            getleafsum(root->l);//遍历树
            getleafsum(root->r);
        }
    }
    return sum;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值