给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N
(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例:
7
1 2 3 4 5 6 7
4 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 51
int 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. 是否完全二叉搜索树
将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果。
输入格式:
输入第一行给出一个不超过20的正整数N;第二行给出N个互不相同的正整数,其间以空格分隔。
输出格式:
将输入的N个正整数顺序插入一个初始为空的二叉搜索树。在第一行中输出结果树的层序遍历结果,数字间以1个空格分隔,行的首尾不得有多余空格。第二行输出“YES”,如果该树是完全二叉树;否则输出“NO”。
输入样例1:9 38 45 42 24 58 30 67 12 51输出样例1:
38 45 24 58 42 30 12 67 51 YES输入样例2:
8 38 24 12 45 58 67 42 51输出样例2:
38 45 24 58 42 12 67 51 NO
#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"); else printf("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 root
:x
是根结点;x and y are siblings
:x
和y
是兄弟结点;x is the parent of y
:x
是y
的父结点;x is a child of y
:x
是y
的一个子结点。
输入格式:
每组测试第1行包含2个正整数N
(≤ 1000)和M
(≤ 20),分别是插入元素的个数、以及需要判断的命题数。下一行给出区间[−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个空格分隔,行首尾不得有多余空格。
- #include <iostream>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #define SizeMax 105
- using namespace std;
- typedef struct Node
- {
- int data;
- Node* lchild;
- Node* rchild;
- } Node;
- Node *CreateBT2(int *post,int *in,int n)
- {
- Node *b;
- int r,*p,k;
- if(n<=0)return NULL;
- r=*(post+n-1);
- b=(Node*)malloc(sizeof(Node));
- b->data=r;
- for(p=in; p<in+n; p++)
- if(*p==r)break;
- k=p-in;
- b->lchild=CreateBT2(post,in,k);
- b->rchild=CreateBT2(post+k,p+1,n-k-1);
- return b;
- }
- void Print(Node *r)
- {
- Node *p;
- Node *pr[SizeMax];
- int rear=-1,front=-1;
- rear++;
- pr[rear]=r;
- while(rear!=front)
- {
- front=(front+1)%SizeMax;
- p=pr[front];
- printf("%d ",p->data);
- if(p->lchild!=NULL)
- {
- rear=(rear+1)%SizeMax;
- pr[rear]=p->lchild;
- }
- if(p->rchild!=NULL)
- {
- rear=(rear+1)%SizeMax;
- pr[rear]=p->rchild;
- }
- }
- }
- int main()
- {
- int N;
- scanf("%d",&N);
- int a[N],b[N];
- for(int i=0; i<N; i++)
- scanf("%d",a+i);
- for(int i=0; i<N; i++)
- scanf("%d",b+i);
- Node* result=CreateBT2(a,b,N);
- Print(result);
- return 0;
- }