11.1再谈树

来源:互联网 发布:手机淘宝用什么付款 编辑:程序博客网 时间:2024/06/08 10:40

有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;}




0 0
原创粉丝点击