11.1再谈树

有n个顶点的树具有以下3个特点:连通,不含圈,恰好包含n-1条边,有意思的是,具备上述3个特点中的任意两个,就可以推出第三个

11.1.1无根树转有根树

分析:

邻接矩阵占用的空间很大,用vector数组即可。由于n个结点的树,只有n-1条边,vector数组实际占用的空间与n成正比

vector<int>G[maxn];
void read_tree(){
    int u,v;
    scanf("%d",&n);
    for(int i=0;i<n-1;i++){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
}
转化过程如下:

void dfs(int u,int fa){  //递归转化以u为根的子树,u的父节点fa
    int d=G[u].size(); //结点u的相邻点个数
    for(int i=0;i<d;i++){
        int v=G[u][i];  //结点u的第i个相邻点V
        if(v!=fa)
            dfs(v,p[v]=u);  //把v的父结点设为u,然后递归
    }
}
主程序设置p[root]=-1(表示根结点的父结点不存在),然后调用dfs(root,-1)即可。初学者最容易犯的错误之一就是忘记判断v是否和父结点相等

11.1.2表达式树

二叉树是表达式处理的常用工具

const int maxn=1000;
int lch[maxn],rch[maxn];
char op[maxn];
int nc=0;
int build_tree(char* s,int x,int y){
    int i,c1=-1,c2=-1,p=0;
    int u;
    if(y-x==1){   //仅一个字符,建立单独结点
        u=++nc;
        lch[u]=rch[u]=0;
        op[u]=s[x];
        return u;
    }
    for(i=x;i<y;i++){
        switch(s[i]){
            case '(': p++; break;
            case ')': p--; break;
            case '+': case '-': if(!p) c1=i; break;
            case '*': case '/': if(!p) c2=i; break;
        }
    }
    if(c1<0) c1=c2;  //找不到括号外的加减法,就要乘除号
    if(c1<0) return build_tree(s,x+1,y-1);  //整个表达式被一对括号括起来
    u=++nc;
    lch[u]=build_tree(s,x,c1);
    rch[u]=build_tree(s,c1+1,y);
    op[u]=s[c1];
    return u;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值