二叉树问题综合求解

来源:互联网 发布:手机端 时间轴 源码 编辑:程序博客网 时间:2024/06/06 09:25
6 玩转二叉树   (25分)

给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。

输入格式:

输入第一行给出一个正整数N\le30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。

输出格式:

在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。

输入样例:

71 2 3 4 5 6 74 1 3 2 6 5 7

输出样例:

4 6 1 7 5 3 2
#include "iostream"#include "queue"#include "stdio.h"using namespace std;#define Max 51int Pre[Max],Mid[Max],N;struct Node{   int Data;   Node *Left;   Node *Right;   Node ()   {     Left=NULL;     Right=NULL;   }};void CreatTree(int PreLeft,int MidLeft,int Len,Node *&p){      if(Len<=0)      {      return ;      }      p=new Node;      p->Data=Pre[PreLeft];        int len,i=MidLeft;      while(Pre[PreLeft]!=Mid[i])      i++;         len=i-MidLeft;      CreatTree(PreLeft+1,MidLeft,len,p->Left);      CreatTree(PreLeft+len+1,i+1,Len-len-1,p->Right);}void Output(Node *p){                   cout<<p->Data;            queue<Node *> Q;         if(p->Left!=NULL)    {    Q.push(p->Left);    }    if(p->Right!=NULL)    {     Q.push(p->Right);    }                     while(!Q.empty())     {        Node *s=Q.front();        Q.pop();    cout<<" "<<s->Data ;    if(s->Left!=NULL)    {    Q.push(s->Left);    }    if(s->Right!=NULL)    {     Q.push(s->Right);    }    }     }void Swap(Node *p ){       if(p==NULL) return;Swap(p->Left);Swap(p->Right); Node *s;    s=p->Left;    p->Left=p->Right;    p->Right=s;}int main(){ //freopen("1.txt","r",stdin);cin>>N;Node *Tree;Tree=NULL;int i,j;for(i=1;i<=N;i++){cin>>Mid[i];}for(j=1;j<=N;j++){cin>>Pre[j];}CreatTree(1,1,N,Tree);Swap(Tree);Output(Tree);cout<<endl;return 0;}

L3-010. 是否完全二叉搜索树

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果。

输入格式:

输入第一行给出一个不超过20的正整数N;第二行给出N个互不相同的正整数,其间以空格分隔。

输出格式:

将输入的N个正整数顺序插入一个初始为空的二叉搜索树。在第一行中输出结果树的层序遍历结果,数字间以1个空格分隔,行的首尾不得有多余空格。第二行输出“YES”,如果该树是完全二叉树;否则输出“NO”。

输入样例1:
938 45 42 24 58 30 67 12 51
输出样例1:
38 45 24 58 42 30 12 67 51YES
输入样例2:
838 24 12 45 58 67 42 51
输出样例2:
38 45 24 58 42 12 67 51NO
#include <iostream>#include <cstdio>#include <cmath>#include <queue>#include <cstring>using namespace std;int tree[200],le[200],ri[200],cnt=0,path[200],p=0,idd[200];bool flag;//建树void insert(int x,int v,int id){    if(tree[x]==0){tree[x]=v;idd[x]=id;cnt++;}else{if(v>tree[x]){if(le[x]==0)  le[x]=cnt+1;insert(le[x],v,id*2);}else{           if(ri[x]==0)   ri[x]=cnt+1;   insert(ri[x],v,id*2+1);}}}//层序遍历void solve(){int cur;queue <int> qe;qe.push(0);while(!qe.empty()){       cur=qe.front();   qe.pop();   //是否是完全二叉树的判断   if(p+1<idd[cur])   flag=0;   path[p++]=tree[cur];   if(le[cur]&&ri[cur])   {   qe.push(le[cur]);   qe.push(ri[cur]);   }   else if(le[cur]||ri[cur])   {   if(le[cur])     qe.push(le[cur]);           else qe.push(ri[cur]);   }}}int main(){int n,tmp;scanf("%d",&n);    for(int i=1;i<=n;i++){scanf("%d",&tmp);insert(0,tmp,1);}flag=1;solve();printf("%d",path[0]);for(int i=1;i<p;i++){printf(" %d",path[i]);}printf("\n");if(flag)printf("YES\n");elseprintf("NO\n");return 0;}
另一种方法处理
#include <stdio.h>#include <algorithm>#include <string.h>#include <queue>#include <iostream>
using namespace std;
typedef long long ll;const int N = 25;
typedef struct Tree{    Tree *left;    Tree *right;    int val;}Tree;
Tree *root;int seq[N], cnt, n;
Tree *creat(int num){    Tree *node = (Tree*)malloc(sizeof(Tree));    node->left = NULL;    node->right = NULL;    node->val = num;    return node;}
Tree *insertt(Tree *node, int num){    if(node == NULL)    {        node = creat(num);    }    else    {        if(num > node->val) node->left = insertt(node->left, num);        else if (num < node->val) node->right = insertt(node->right, num);    }    return node;}
void levelorder(Tree *cur){    queue<Tree*>que;    while(!que.empty()) que.pop();    que.push(cur);    Tree *node;    int flag = 0, vis = 0;//flag判断是否是完全二叉树,vis判断是否访问过    while(!que.empty())    {        node = que.front();        que.pop();
        //判断完全二叉树        if(!vis)        {            if((node->left==NULL && node->right==NULL) || (node->left!=NULL && node->right==NULL))            {                flag = 1;                vis = 1;            }            else if(node->left==NULL && node->right!=NULL)            {                flag = 0;                vis = 1;            }        }        else        {            if(node->left!=NULL || node->right!=NULL) flag = 0;        }
        if(cnt == n-1) printf("%d\n", node->val);        else        {            printf("%d ", node->val);            cnt++;        }        if(node->left != NULL) que.push(node->left);        if(node->right != NULL) que.push(node->right);    }    if(flag) printf("YES\n");    else printf("NO\n");}
void build(){    root = NULL;    cnt = 0;    for(int i = 0; i < n; i++)    {        int num = seq[i];        root = insertt(root, num);    }}
int main(){  //  freopen("in.txt", "r", stdin);    while(~scanf("%d", &n))    {        for(int i = 0; i < n; i++)            scanf("%d", &seq[i]);        build();        levelorder(root);    }}

将一系列给定数字顺序插入一个初始为空的小顶堆H[]。随后判断一系列相关命题是否为真。命题分下列几种:

  • x is the rootx是根结点;
  • x and y are siblingsxy是兄弟结点;
  • x is the parent of yxy的父结点;
  • x is a child of yxy的一个子结点。

输入格式:

每组测试第1行包含2个正整数N\le 1000)和M\le 20),分别是插入元素的个数、以及需要判断的命题数。下一行给出区间[-10000, 10000][10000,10000]内的N个要被插入一个初始为空的小顶堆的整数。之后M行,每行给出一个命题。题目保证命题中的结点键值都是存在的。

输出格式:

对输入的每个命题,如果其为真,则在一行中输出T,否则输出F

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<map>using namespace std;int n, a[1005];//建树的 “模板”void up( int son ){    int t = a[son];    int tson = son;    while( (tson > 1)&&( a[tson/2] > t))    {        a[tson] = a[tson/2];        tson = tson/2;    }    a[tson] = t;}void charu( int  t){    a[ ++n ] = t;    up( n );}int main (){    int k, m, x, y;;    map <int, int> index; //记录下标    string s;    cin >> k >> m;    n=0;    //建树    for(int i=0; i<k; i++)    {        cin >> x;        charu(x);    }    //给map赋值    for(int i=1; i<=n; i++)    {        index[a[i]] = i;    }    for(int i=0; i<m; i++)    {        cin >> x;        cin >> s;        int index_x = index[x];         int index_y;        if(s[0] == 'a')        {            cin >> y;            getline(cin, s);  //这个函数可以输入一个带空格的字符串            index_y = index[y];            if(index_x/2 == index_y/2)                puts("T");            else                puts("F");        }        else        {            cin >> s;            cin >> s;            if(s[0] == 'r')            {                if(index_x == 1)                    puts("T");                else                    puts("F");            }            else if(s[0] == 'p')            {                cin >> s;                cin >> y;                index_y = index[y];                if(index_y/2 == index_x)                    puts("T");                else                    puts("F");            }            else            {                cin >> s;                cin >> y;                index_y = index[y];                if(index_x/2 == index_y)                    puts("T");                else                    puts("F");            }        }    }    return 0;}

一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,

  • 其左子树中所有结点的键值小于该结点的键值;
  • 其右子树中所有结点的键值大于等于该结点的键值;
  • 其左右子树都是二叉搜索树。

所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。

给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>typedef struct node{    int data;    struct node *l;    struct node *r;}Node;int s[1010];int v[1010];int tmp;void create1(Node *root,int x)//构造原二叉树{    Node *p;    if(x<root->data)    {        if(root->l==NULL)        {            p = new Node;            p->data = x;            p->l = NULL;            p->r = NULL;            root->l = p;            return;        }        else            create1(root->l,x);    }    else    {        if(root->r==NULL)        {            p = new Node;            p->data = x;            p->l = NULL;            p->r = NULL;            root->r = p;            return;        }        else            create1(root->r,x);    }}void create2(Node *root,int x)//构造镜像二叉树{    Node *p;    if(x>=root->data)    {        if(root->l==NULL)        {            p = new Node;            p->data = x;            p->l = NULL;            p->r = NULL;            root->l = p;            return;        }        else            create2(root->l,x);    }    else    {        if(root->r==NULL)        {            p = new Node;            p->data = x;            p->l = NULL;            p->r = NULL;            root->r = p;            return;        }        else            create2(root->r,x);    }}void firstvisit(Node *p){    if(p!=NULL)    {        v[tmp++] = p->data;        firstvisit(p->l);        firstvisit(p->r);    }}void lastvisit(Node *p){    if(p!=NULL)    {        lastvisit(p->l);        lastvisit(p->r);        v[tmp++] = p->data;    }}int main(){    int n,flag;    Node *root,*toor;    root = NULL;    scanf("%d",&n);    for(int i=0;i<n;i++)    {        scanf("%d",&s[i]);        if(i==0)//构造根节点        {            root = new Node;            root->data = s[i];            root->l = NULL;            root->r = NULL;            toor = new Node;            toor->data = s[i];            toor->l = NULL;            toor->r = NULL;        }        else        {            create1(root,s[i]);            create2(toor,s[i]);        }    }    tmp = 0;    flag = 1;    firstvisit(root);    for(int i=0;i<n;i++)    {        if(s[i]!=v[i])        {            flag = 0;break;        }    }    if(flag==1)    {        printf("YES\n");        tmp=0;        lastvisit(root);        for(int i=0;i<n;i++)        {            printf("%d",v[i]);            if(i!=n-1)                printf(" ");        }    }    else    {        tmp=0;        flag =1;        firstvisit(toor);        for(int i=0;i<n;i++)        {            if(s[i]!=v[i])            {                flag=0;break;            }        }        if(flag==1)        {            printf("YES\n");            tmp=0;            lastvisit(toor);            for(int i=0;i<n;i++)            {                printf("%d",v[i]);                if(i!=n-1)                    printf(" ");            }        }        else            printf("NO");    }    return 0;}

给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。

输入格式:

输入第一行给出一个正整数N(<=30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。

输出格式:

在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。

  1. #include <iostream>  
  2. #include <stdio.h>  
  3. #include <string.h>  
  4. #include <stdlib.h>  
  5. #define SizeMax 105  
  6. using namespace std;  
  7. typedef struct Node  
  8. {  
  9.     int data;  
  10.     Node* lchild;  
  11.     Node* rchild;  
  12. } Node;  
  13. Node *CreateBT2(int *post,int *in,int n)  
  14. {  
  15.     Node *b;  
  16.     int r,*p,k;  
  17.     if(n<=0)return NULL;  
  18.     r=*(post+n-1);  
  19.     b=(Node*)malloc(sizeof(Node));  
  20.     b->data=r;  
  21.     for(p=in; p<in+n; p++)  
  22.         if(*p==r)break;  
  23.     k=p-in;  
  24.     b->lchild=CreateBT2(post,in,k);  
  25.     b->rchild=CreateBT2(post+k,p+1,n-k-1);  
  26.     return b;  
  27. }  
  28. void Print(Node *r)  
  29. {  
  30.     Node *p;  
  31.     Node *pr[SizeMax];  
  32.     int rear=-1,front=-1;  
  33.     rear++;  
  34.     pr[rear]=r;  
  35.     while(rear!=front)  
  36.     {  
  37.         front=(front+1)%SizeMax;  
  38.         p=pr[front];  
  39.         printf("%d ",p->data);  
  40.         if(p->lchild!=NULL)  
  41.         {  
  42.             rear=(rear+1)%SizeMax;  
  43.             pr[rear]=p->lchild;  
  44.         }  
  45.         if(p->rchild!=NULL)  
  46.         {  
  47.             rear=(rear+1)%SizeMax;  
  48.             pr[rear]=p->rchild;  
  49.         }  
  50.     }  
  51. }  
  52. int main()  
  53. {  
  54.     int N;  
  55.     scanf("%d",&N);  
  56.     int a[N],b[N];  
  57.     for(int i=0; i<N; i++)  
  58.         scanf("%d",a+i);  
  59.     for(int i=0; i<N; i++)  
  60.         scanf("%d",b+i);  
  61.     Node* result=CreateBT2(a,b,N);  
  62.     Print(result);  
  63.     return 0;  
  64. }  


0 0
原创粉丝点击