uva-二叉树的遍历

代码测试与树遍历实战

代码测试一定要严谨!代码测试一定要严谨!代码测试一定要严谨!
今天就是因为complete写成了complet,结果提交了n次,恨死我~
先说下今天做的几个题目,今天主要做了紫书,有关树的遍历的部分题目,熟悉了BFS与DFS的相应操作,然而虽然之前已经学了数据结构的相关知识,现在却忘的差不多了,所以,菜鸡只好比着紫书上的代码,一点点的将之前的东西拾起来,所以本文的代码基本上与紫书一致。不得不说,大佬就是大佬,看人家的代码竟有一丝享受,实在是妙。

uva-122

这道题目是给定如(12,LLLLL)的序列,判断所给序列是否合法(即是完整的树,其各结点值不冲突),若合法则按层次遍历该序列
使用的技巧:
数据的输入,使用字符串s输入的特性,即以\0停止,自然将每个()作为一次输入,然后使用strcmp检验停止标记空(),再用sscanf提取数值,最后用strchr,提取路径首位置
直接上代码

#include<bits/stdc++.h>
using namespace std;
const int maxn =1e5+5;
struct Node
{
    bool have_value;
    int v;
    Node *left,*right;
    Node():have_value(false),left(NULL),right(NULL){}//构造函数
};
Node *root=NULL;
bool failed=false;
Node *newnode()
{
    return new Node();
}
void addNode(int v,char *s)
{
    int n=strlen(s);
    Node *u=root;
    for(int i=0;i<n;i++)
    {
        if(s[i]=='L')
        {
            if(u->left==NULL)
            {
                u->left=newnode();
            }
            u=u->left;
        }
        else if(s[i]=='R')
        {
            if(u->right==NULL)
            {
                u->right=newnode();
            }
            u=u->right;
        }
    }
    if(u->have_value)
        failed=true;
    u->v=v;
    u->have_value=true;
}
void remove_tree(Node* u)//删除占用的内存
{
    if(u==NULL)
        return ;
    remove_tree(u->left);
    remove_tree(u->right);
    delete u;
}
bool read_input()
{
    //初始化
    failed=false;
    remove_tree(root);
    root=newnode();
    for(;;)
    {
       char s[maxn];
        if(scanf("%s",s)!=1)//以空白字符为分隔符
            return false;
        if(!strcmp(s,"()"))
            break;
        int v;
        sscanf(&s[1],"%d",&v);
        addNode(v,strchr(s,',')+1);
    }
    return true;
}
bool bfs(vector<int> &ans)
{
    queue<Node*>q;
    ans.clear();
    q.push(root);
    while(!q.empty())
    {
        Node *u=q.front();
        q.pop();
        if(!u->have_value)
            return false;
        ans.push_back(u->v);
        if(u->left!=NULL)
            q.push(u->left);
        if(u->right!=NULL)
            q.push(u->right);
    }
    return true;
}
int main()
{

    for(;;)
    {
        if(read_input()==false)
            break;
        if(failed)
            printf("not complete\n");
        else
        {
            vector<int> ans;
            if(!bfs(ans))
               printf("not complete\n");
            else
            {
                for(int i=0;i<ans.size();i++)
                {
                    if(i)
                        printf(" ");
                    printf("%d",ans[i]);
                }
                printf("\n");
            }

        }

    }
}

uva548

本题是由中序和后序序列构造树,然后从构造后的树中进行dfs选择符合题意得值

#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
int in_order[maxn]={0};
int post_order[maxn]={0};
int n;
int lch[maxn]={0};
int rch[maxn]={0};
int Min,Min_num;
bool read_list(int *a)
{
    string line ;
    if(!getline(cin,line))
        return false;
    stringstream ss(line);
    n=0;
    int x;
    while(ss>>x)
    {
        a[n++]=x;
    }
    return n>0;
}
int build(int L1,int R1,int L2,int R2)//L1,R1前序起止,L2,R2后序起止
{
    if(L1>R1||L2>R2)
        return 0;
    int root=post_order[R2];
    int p=L1;
    while(in_order[p]!=root)
        p++;
    int cnt=p-L1;//走过的元素
    lch[root]=build(L1,p-1,L2,L2+cnt-1);
    rch[root]=build(p+1,R1,L2+cnt,R2-1);
    return root;
}
void dfs(int u,int sum)
{
    sum+=u;
    if(!lch[u]&&!rch[u])
    {
        if((sum<Min)||(sum==Min&&u<Min_num))
        {
            Min=sum;
            Min_num=u;;
        }
    }
    if(lch[u])
        dfs(lch[u],sum);
    if(rch[u])
        dfs(rch[u],sum);
}
int main()
{
    while(read_list(in_order))
    {
        read_list(post_order);
        Min=1000000;
        Min_num=1000000;
        build(0,n-1,0,n-1);
        dfs(post_order[n-1],0);
        printf("%d\n",Min_num);
        memset(in_order,0,n);
        memset(post_order,0,n);
        memset(lch,0,maxn);
        memset(rch,0,maxn);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值