感觉树的问题难在建树,建树的方法,
1.完全二叉树:递归build(l) build(r) mid赋值 ,位置也就是id已经决定这个点在哪里了
2.正常的树:位置无法决定,g[i].push_bakc().....
16天梯赛 7-10 树的遍历 【中序+后序 --》层次】
收获总结:
二叉树的特点 中:l 左:2l 右:2l+1
建立树的特点---》 tree[i]=.. build(mid*2) build(mid*2+1) 先序 中序,后序就是位置不一样
遍历的特点---》 cout<<mid; build(l) build(r) 先序 中序 后序也就是位置不一样 PK 层次1~n遍历!!!!
7-10 树的遍历
分数 25
全屏浏览
切换布局
作者 陈越
单位 浙江大学
给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出样例:
4 1 6 3 5 7 2
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int inf = 1e18;
const int N = 1e4 + 10;
int gcd(int a, int b)
{
return a == 0 ? b : gcd(b % a, a);
}
int lcm(int a, int b)
{
return a / gcd(a, b) * b;
}
int n;
int a[N],b[N],p[N];//后序,中序,后序的数字在中序中的位置
vector<vector<int> >tre(N);//建树
//由后序来定根节点,由中序来定左右两边 建树来记录每个根节点的子树有哪些
//利用中序和后序的特点【后序的最后一位为根节点,中序的根节点左边为左子树,右边为右子树】,来递归建树,每次记录遍历中后序左右子树的范围
int build(int al,int ar,int bl,int br)
{
if(al>ar||bl>br)
return -1;//若越界则说明结束
int root=a[ar];//根节点为后序的最后一个字母
int mid=0;//记录属于左子树的有多少个点
while(b[bl+mid]!=root)//遍历中序可以得到中序从头开始的有多少个属于左半边
++mid;
//后序的左右两半,中序的左右两半
//a[al,al+mid-1] [al+mid,ar-1] b[bl,bl+mid-1] [bl+mid+1,br]
int ch_l=build(al,al+mid-1,bl,bl+mid-1);
int ch_r=build(al+mid,ar-1,bl+mid+1,br);
//树的存储
if(ch_l!=-1)
tre[root].push_back(ch_l);
if(ch_r!=-1)
tre[root].push_back(ch_r);
return root;
}
void bfs(int root)//树的层次遍历,一个根一个根存到队列里面再输出
{
queue<int>q;
q.push(root);
int id=1;
while(q.size())
{
int tn=q.front();
if(id<n)
{
cout<<tn<<" ";
++id;
}
else
cout<<tn<<endl;
//输出格式,只有最后一个的后面没有" "
q.pop();
for(int i=0; i<tre[tn].size(); i++)
{
q.push(tre[tn][i]);
}
}
return;
}
void solve()
{
cin>>n;
for(int i=1; i<=n; i++)
cin>>a[i];//后序
for(int i=1; i<=n; i++)
{
cin>>b[i];//中序
}
int root=build(1,n,1,n);
bfs(root);
//后序的最后一个就是中间的
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T = 1;
// cin>>T;
while (T--)
{
solve();
}
return 0;
}
L2-3 完全二叉树的层序遍历【二叉树的性质 后序--》层次】
分数 25
全屏浏览
切换布局
作者 陈越
单位 浙江大学
一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是完美二叉树。对于深度为 D 的,有 N 个结点的二叉树,若其结点对应于相同深度完美二叉树的层序遍历的前 N 个结点,这样的树就是完全二叉树。
给定一棵完全二叉树的后序遍历,请你给出这棵树的层序遍历结果。
输入格式:
输入在第一行中给出正整数 N(≤30),即树中结点个数。第二行给出后序遍历序列,为 N 个不超过 100 的正整数。同一行中所有数字都以空格分隔。
输出格式:
在一行中输出该树的层序遍历序列。所有数字都以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
8
91 71 2 34 10 15 55 18
输出样例:
18 34 55 71 2 10 15 91
思路:二叉树的题目一定要建树 看给了什么顺序,然后模板递归建树,给树填值。层次遍历就是1~n按顺序打印下来
代码实现:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 10;
const int inf = 1e18;
int n;
int tree[N];
int a[N];
int id=1;
void build(int l)
{
if(l>n)
return;
build(l*2),build(l*2+1);//构建左右子树
tree[l]=a[id++];//左右中,中间的数值为后序的顺序
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
build(1);
for(int i=1;i<=n;i++)
{
if(i!=1)
cout<<" ";
cout<<tree[i];
}
cout<<endl;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T = 1;
//cin>>T;
while (T--)
{
solve();
}
return 0;
}