二叉树


#include<bits/stdc++.h>
using namespace std;
const int N=100+10;
const int inf=0x3f3f3f3f;
struct node
{
    char data;
    struct node *l,*r;
}*root;
void built(char x[],char z[],int len,node* &tmp)
{
    if(len==0) return;
    int index=0;
    tmp=new node;//申请空间
    tmp->data=*x;
    tmp->l=NULL;
    tmp->r=NULL;
    while(index<len)
    {
        if(z[index]==*x) break;
        index++;
    }
    built(x+1,z,index,tmp->l);
    built(x+1+index,z+index+1,len-index-1,tmp->r);
}
void print(node *t)//三序遍历
{
    if(t){
        printf("%c ",t->data);
        print(t->l);
        print(t->r);
    }
}
void bfs(node *t)//层序遍历
{
    queue<node*> q;
    q.push(t);
    while(!q.empty())
    {
        node* tmp =q.front();q.pop();
        printf("%c ",tmp->data);
        if(tmp->l) q.push(tmp->l);
        if(tmp->r) q.push(tmp->r);
    }cout<<endl;
}
int high(node *t)//深度
{
    if(!t) return 0;
    return max(high(t->l),high(t->r))+1;
}
int main()
{
    int n;cin>>n;
    char xian[N],zhong[N];
    for(int i=0;i<n;i++) cin>>xian[i];
    for(int i=0;i<n;i++) cin>>zhong[i];
    built(xian,zhong,n,root);
    print(root);cout<<endl;
    printf("%d\n",high(root));
    bfs(root);
    return 0;
}


根据后序和中序遍历输出先序遍历   (25分)

本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。

输入格式:

第一行给出正整数NNN(≤30\le 3030),是树中结点的个数。随后两行,每行给出NNN个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。

输出格式:

在一行中输出Preorder:以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。

输入样例:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

输出样例:

Preorder: 4 1 3 2 6 5 7

#include<bits/stdc++.h>
using namespace std;
const int N=100+10;
const int inf=0x3f3f3f3f;
int a[N],b[N],c[N];//前中后
int k=0,n;
void solve(int h[],int z[],int len)
{
    if(len<=0) return;
    int tmp=h[len-1];
    a[k++]=tmp;
    int index=0;
    while(index<len)
    {
        if(z[index]==tmp) break;
        index++;
    }
    solve(h,z,index);
    solve(h+index,z+index+1,len-index-1);
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++) cin>>c[i];
    for(int i=0;i<n;i++) cin>>b[i];
    solve(c,b,n);
    printf("Preorder:");
    for(int i=0;i<n;i++) printf(" %d",a[i]);
    printf("\n");
    return 0;
}

根据两种遍历顺序确定树结构(build-tree)

题目描述
输入
第1行:二叉树的前序遍历顺序

第2行:中序遍历顺序

输出
二叉树的后序遍历顺序

样例输入

ABCDEFGH
CBEDAGHF

样例输出
CEDBHGFA

 

分析:

这道题最核心的问题在于如何建树(或模拟建树),类似于分治(递归) ,我们设先序串为a,中序串为b,用全局变量s表示在a中查找到了第几个数

先看样例,从a可知A是根节点,再根据中序遍历的性质判定在b中,A的左儿子一定在A的左边,右儿子一定在A的右边

再由先序遍历的性质得B是A的左儿子,此时s=1,再递归搜索B的左右儿子,当B搜完后,s=5(F),那么A的右儿子就是F,再递归搜索F的左右儿子,整个程序就可以递归了

当带参数的时候应该规定当前结点的左右儿子应该在哪个范围里找,否则会错乱


#include<bits/stdc++.h>
using namespace std;
const int N=1000+10;
const int inf=0x3f3f3f3f;
char a[N],b[N],c[N];//前中后
int s=1,n;
struct node
{
    int l,r;
}f[260];
void dfs(int q,int w,int o)
{
    if(s==n+1) return;
    for(int i=1;i<=w;i++)
    if(b[i]==a[s])
    {
        if(!f[o].l) f[o].l=b[i];
        else f[o].r=b[i];
        s++;
        dfs(q,i-1,b[i]);
        dfs(i+1,w,b[i]);
    }
}
void hdfs(int a)
{
    if(a)
    {
        hdfs(f[a].l);
        hdfs(f[a].r);
        printf("%c",a);
    }
}
int main()
{
    scanf("%s%s",a+1,b+1);
    n=strlen(a+1);
    dfs(1,n,0);
    hdfs(a[1]);
    return 0;
}

还原二叉树   (25分)

给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。

输入格式:

输入首先给出正整数N(≤\le50),为树中结点总数。下面两行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区别大小写)的字符串。

输出格式:

输出为一个整数,即该二叉树的高度。

输入样例:

9
ABDFGHIEC
FDHGIBEAC

输出样例:

5

#include<bits/stdc++.h>  
using namespace std;  
struct Tree{    //树的节点   
    char data;  
    struct Tree *lchild;  
    struct Tree *rchild;  
}treenode,*tree;  
tree t = NULL;  
void xianzhong(char x[],char z[],int size,tree &tmp){  ///根据先序中序构造二叉树   
    if(size == 0) return;      ///注意引用的使用   
    int index = 0;  
    tmp = (tree)malloc(sizeof(treenode));   ///需要为节点分配空间   
    tmp->data = *x;     ///先序的子序列的第一个元素是其根节点   
    tmp->lchild = NULL;     ///注意这里的初始化很重要   
    tmp->rchild = NULL;   
    while(index < size){    ///每次找到先序的根节点的位置   
        if(*(z+index) == *x) break;  
        index++;  
    }  
    xianzhong(x+1,z,index,tmp->lchild);    ///构造左孩子   
    xianzhong(x+1+index,z+index+1,size-index-1,tmp->rchild);  ///构造右孩子   
}  
  
void print(tree t){   //先序输出,调试时使用   
    if(t != NULL){  
        printf("%d ",t->data);  
        print(t->lchild);  
        print(t->rchild);  
    }  
}  
int high(tree t){   ///计算树的深度   
    if(!t) return 0;     
    int lh = high(t->lchild);   ///递归找到叶子,然后从叶子节点一层一层往上数   
    int rh = high(t->rchild);  
    if(lh > rh) return ++lh;    ///那边高度高就在那边加1   
    return ++rh;  
      
}  
int main() 
{  
    int n;  
    scanf("%d",&n);  
    char xianxu[55];    ///先序序列   
    char zhongxu[55];   ///中序序列   
    scanf("%s%s",xianxu,zhongxu);  
    xianzhong(xianxu,zhongxu,n,t);  
    printf("%d\n",high(t));  
    return 0;  
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值