二叉树专题训练



HDU 3999 The order of a Tree

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3999


题意: 给含n个数的序列,该序列可以构成一颗二叉搜索树,求寻找字典序最小的插入顺序,来构成一颗相同的树。

思路: 二叉搜索树的左儿子小于父节点,右儿子大于父节点。想要字典序最小的插入顺序构成的树和标准树一样,那么根就需要一样,因此要按照先根(保证树是一样的),再左,再右(字典序最小)。先序遍历即为从小到大排好的序列,所以这里其实就是先建树再输出二叉树的先序遍历。


Code(C++):

#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct node{
    int data;
    node *lchild,*rchild;
}*Tree,tree;
Tree root;
int n;
void Insert(Tree& root,int x){
    if(root==NULL){
        root=(Tree)malloc(sizeof(tree));
        root->data=x;
        root->lchild=NULL;
        root->rchild=NULL;
    }
    else if(x < root->data)
        Insert(root->lchild,x);
    else
        Insert(root->rchild,x);
}
void preoder(Tree root,int& cnt){
    if(root==NULL)  return;
    cnt++;
    if(cnt==n)
        cout<<root->data<<endl;
    else
        cout<<root->data<<" ";
    preoder(root->lchild,cnt);
    preoder(root->rchild,cnt);
}
int main(){
    while(cin>>n){
        int x;
        for(int i=1;i<=n;i++){
            cin>>x;
            Insert(root,x);
        }
        int cnt=0;
        preoder(root,cnt);
    }
    return 0;
}


HDU 3791 二叉搜索树

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3791


题意: 判断两序列是否为同一二叉搜索树序列

思路: 先将一开始给你的序列生成一个二叉搜索树用数组 tree1[ ] 存储起来,
然后输入n个序列,每一个序列都生成一个二叉搜索树建立一个临时数组 tree2[ ] 存储,比较两个数组是否相同,相同输出“YES”,不同输出“NO”。


Code1(C++):

#include <iostream>
#include <cstring>
using namespace std;
char s[20];
int tree1[25000],tree2[25000];
void Insert(char ch,int *tree){ //插入数
    int pos=1;
    int value=ch-'0';
    while(tree[pos]!=-1){
        if(tree[pos]<value)
            pos=pos*2+1;
        else
            pos*=2;
    }
    tree[pos]=value;
}
void Btree(char *str,int *tree){    //建树
    tree[1]=str[0]-'0';
    for(int i=1;i<strlen(str);i++)
        Insert(str[i],tree);
}
int main(){
    int n;
    while(cin>>n,n){
        cin>>s;
        memset(tree1,-1,sizeof(tree1));
        Btree(s,tree1);
        while(n--){
            cin>>s;
            memset(tree2,-1,sizeof(tree2));
            Btree(s,tree2);
            int i;
            for(i=0;i<5000;i++){
                if(tree1[i]!=tree2[i])
                    break;
            }
            if(i==5000)
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }
    }
    return 0;
}

Code2(C++):

#include <iostream>
#include <malloc.h>
#include <cstring>
using namespace std;
int cnt;
char str1[25],str2[25];
int tree1[25],tree2[25];
typedef struct node{
    int data;
    node *left,*right;
}*tree,Tree;
tree Insert(int t,tree p){
    if(!p){
        p=(tree)malloc(sizeof(Tree));
        p->data=t;
        p->left=NULL;
        p->right=NULL;
    }else{
        if(t < p->data)
            p->left = Insert(t,p->left);
        else if(t > p->data)
            p->right = Insert(t,p->right);
    }
    return p;
}
void preorder(tree p){
    if(p){
        tree2[cnt++] = p->data;
        preorder(p->left);
        preorder(p->right);
    }
}
int main(){
    int n;
    while(cin>>n,n){
        cin>>str1;
        tree root=NULL;
        int value;
        int len=strlen(str1);
        for(int i=0;i<len;i++){
            value=str1[i]-'0';
            root=Insert(value,root);
        }
        cnt=0;
        preorder(root);
        for(int i=0;i<len;i++)
            tree1[i]=tree2[i];
        while(n--){
            cin>>str2;
            root=NULL;
            len=strlen(str2);
            for(int i=0;i<len;i++){
                value=str2[i]-'0';
                root=Insert(value,root);
            }
            cnt=0;
            preorder(root);
            int k;
            for(k=0;k<len;k++)
                if(tree1[k]!=tree2[k])  break;
            if(k!=len)
                cout<<"NO"<<endl;
            else
                cout<<"YES"<<endl;
        }
    }
    return 0;
}


POJ 2418 Hardwood Species

原题链接:http://poj.org/problem?id=2418


题意: 输入一系列字符串,按字典序从小到大输出字符串和它所占的百分比。

思路: 可以用STL容器中的map来记录字符串个数;也可以用二叉搜索树来做。


Code1(C++):

getline() 函数可以直接读入一整行的内容,遇到换行符停止读入。

#include <iostream>
#include <map>
#include <iomanip>
using namespace std;
int main(){
    ios::sync_with_stdio(0);
    map<string, int> mp;
    map<string, int>::iterator it;
    int sum=0;
    string str;
    while(getline(cin,str)){
        mp[str]++;
        sum++;
    }
    for(it=mp.begin();it!=mp.end();it++)
        cout<<it->first<<" "<<fixed<<setprecision(4)<<(it->second)*1.0/sum*100.0<<endl;
    return 0;
}

Code2(C++):

二叉搜索树做法,G++不能过,C++能过。。。

#include<iostream>
#include <cstring>
#include <cstdio>
#include <iomanip>
using namespace std;
struct node{
    int num;
    char value[35];
    node *lchild;
    node *rchild;
};
void Insert(node* &root,char *str){
    if(root==NULL){
        root=new node;
        strcpy(root->value,str);
        root->lchild=NULL;
        root->rchild=NULL;
        root->num=1;
        return;
    }
    if(strcmp(root->value,str)>0)
        Insert(root->lchild,str);
    else if(strcmp(root->value,str)<0)
        Insert(root->rchild,str);
    else{
        root->num++;
        return;
    }
}
void preorder(node* root,int sum){
    if(root==NULL)  return;
    preorder(root->lchild,sum);
    cout<<root->value<<" "<<fixed<<setprecision(4)<<(double)(root->num)*1.0/sum*100.0<<endl;
    preorder(root->rchild,sum);
}
int main(){
    char str[35];
    node* root=NULL;
    int sum=0;
    while(gets(str)){
        Insert(root,str);
        sum++;
    }
    preorder(root,sum);
    return 0;
}


发布了123 篇原创文章 · 获赞 57 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44668898/article/details/102931923
今日推荐