二叉树问题综合求解
来源:互联网 发布:手机端 时间轴 源码 编辑:程序博客网 时间:2024/06/06 09:25
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N
(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树反转后的层序遍历的序列。数字间以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. 是否完全二叉搜索树
将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果。
输入格式:
输入第一行给出一个不超过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 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;
- }
- 二叉树问题综合求解
- 求解算术表达式结合二叉树的后缀表达式问题
- 【面试】基于二叉树层次遍历相关问题的求解
- LeetCode系列之二叉树最大深度求解问题 C++
- 二叉树的性质综合
- 求解二叉树的深度
- 二叉树代数求解表达式
- UVA 546 Tree (二叉树综合运用)
- Catalan数—求解n个节点能组成的二叉树个数问题
- Catalan数—求解n个节点能组成的二叉树个数问题
- 利用二叉树的非递归后序遍历求解最近公共祖先问题
- 分治法求解二叉树深度
- 利用完全二叉树快速求解LCA
- 二叉树中路径的求解
- 求解二叉树高度的递归算法
- 使用二叉表达式树求解表达式
- 二叉树遍历序列的求解
- 通过遍历求解二叉树结构poj2255
- 数据库自动增长,python解二元一次方程
- C++单例模式原理与实现
- 深度学习小白——最优化问题
- action中如何获取上传文件的文件名和类型
- java 继承
- 二叉树问题综合求解
- stat 出现的三种时间:
- c语言--static和extern关键字
- css3 border-radius详解
- tomcat下部署了多个项目启动报错java web error:Choose unique values for the 'webAppRootKey' context-param in your
- javaweb中关于引用css和image的路径问题
- hdu1878 欧拉回路(无向图+并查集)
- 1003. Emergency (25)
- ajax基础用法