树的遍历方式例题
。。。天梯模拟赛没写出树的遍历。。。补几道类似的题
L2-004 这是二叉搜索树吗?
链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805070971912192
思路:先核对这串序列是否符合先序遍历,如果不符合再核对下是否符合镜像后的,因为题目要求给出树的后序遍历,所以每次核对的时候都按照后序遍历存点。
实现代码:
#include<bits/stdc++.h> using namespace std; vector<int>v; int a[1010],is; void dfs(int l,int r){ if(l > r) return ; int tr = l+1; int tl = r; if(!is){ while(tr <= r&&a[tr] < a[l]) tr++; while(tl > l&&a[tl] >= a[l]) tl--; } else{ while(tr <= r&&a[tr] >= a[l]) tr++; while(tl > l&&a[tl] < a[l]) tl--; } if(tr - tl != 1) return ; dfs(l+1,tl); dfs(tr,r); v.push_back(a[l]); } int main() { int n; cin>>n; for(int i = 0;i < n;i ++){ cin>>a[i]; } dfs(0,n-1); if(v.size()!=n){ is = 1; v.clear(); dfs(0,n-1); } if(v.size() != n) cout<<"NO"<<endl; else{ cout<<"YES"<<endl; for(int i = 0;i < n;i ++){ cout<<v[i]; if(i != n-1) cout<<" "; } cout<<endl; } }
L2-006 树的遍历
链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805069361299456
思路:后序遍历最后一个点是根,我们得到这个根,在中序遍历上找到这个根的位置p,可以以此推出左子树的大小为p-l1,这样两个序的左右子树的区间都可以被找到,保存下当前根节点左右子节点的值,然后用bfs跑出层次遍历的序列。
实现代码:
#include<bits/stdc++.h> using namespace std; const int M = 1e3+10; int post_order[M],in_order[M],lch[M],rch[M],n; int build(int l1,int r1,int l2,int r2){ if(l1 > r1) return 0; int rt = post_order[r2]; int p = l1; while(in_order[p]!=rt) p++; int cnt = p-l1; lch[rt] = build(l1,p-1,l2,l2+cnt-1); rch[rt] = build(p+1,r1,l2+cnt,r2-1); return rt; } void bfs() { queue<int>q; vector<int>v; q.push(build(0,n-1,0,n-1)); while(!q.empty()){ int cur = q.front(); q.pop(); v.push_back(cur); if(lch[cur]) q.push(lch[cur]); if(rch[cur]) q.push(rch[cur]); } for(int i = 0;i < v.size();i ++){ cout<<v[i]; if(i != v.size()-1) cout<<" "; } cout<<endl; } int main() { cin>>n; for(int i = 0;i < n;i ++) cin>>post_order[i]; for(int i = 0;i < n;i ++) cin>>in_order[i]; bfs(); return 0; }
L2-011 玩转二叉树
链接: https://pintia.cn/problem-sets/994805046380707840/problems/994805065406070784
思路; 之前比赛没写来,写完上面两道题后就秒a了。。。
跟前一道基本一样,就是后序换成了前序,这个知道了原理就很好处理了就是根的在第一个罢了。后面镜像操作,我们存左右儿子的时候直接交换存就好了。
实现代码;
#include<bits/stdc++.h> using namespace std; const int M = 1e3 + 10; int pre[M],mid[M],lch[M],rch[M],n; int build(int l1,int r1,int l2,int r2){ if(l1 > r1) return 0; int rt = pre[l2]; int p = l1; while(mid[p] != rt) p++; int cnt = p-l1; rch[rt] = build(l1,p-1,l2+1,l2+cnt); lch[rt] = build(p+1,r1,l2+cnt+1,r2); return rt; } void bfs( ){ vector<int>v; queue<int>q; q.push(build(0,n-1,0,n-1)); while(!q.empty()){ int cur = q.front(); q.pop(); if(lch[cur]) q.push(lch[cur]); if(rch[cur]) q.push(rch[cur]); v.push_back(cur); } for(int i = 0;i < v.size();i ++){ cout<<v[i]; if(i != v.size()-1) cout<<" "; } cout<<endl; } int main() { cin>>n; for(int i = 0;i < n;i ++){ cin>>mid[i]; } for(int i = 0;i < n;i ++){ cin>>pre[i]; } bfs(); return 0; }