二叉树专题学习(C++版) 基础的上机题
前言:
由于二叉树这一章的题型比较多,涉及到的递归程序也较多,所以单开一个随笔来记录这个学习过程,希望对读者有帮助。
理论知识基础
在二叉树的选择题中,常常会涉及到对于最多或最少结点、最大或最小高度、求叶子结点个数这几类经典的问题。
上机题
1.二叉树的建立和遍历
- 这题考察输入每个结点和其左右子树,然后前序遍历。
- 这题考察给你所有叶子结点,让你建立一颗满二叉树。
- dfs前序遍历树
#include <bits/stdc++.h> #define int long long using namespace std; #define endl '\n' vector<int>ve[100005]; map<int,int>cnt; void dfs(int x) { if(ve[x].size()==0) return ; for(auto t:ve[x]) { cout<<" "<<t; dfs(t); } } void solve() { int n; int maxx=-1; cin >> n; int root=0; for (int i = 1; i <= n; i++) { int u; cin>>u; cnt[u]++; ve[u].push_back(i); if(u==0) root=i; } maxx=cnt[root]; int flag=0; for(int i=1;i<=n;i++) { sort(ve[i].begin(),ve[i].end()); if(ve[i].size()!=0 ) if(ve[i].size()!=maxx) flag=1; } cout<<maxx<<" "; if(flag) cout<<"no"; else cout<<"yes"; cout<<endl; cout<<root; dfs(root); } signed main() { int t = 1; // cin>>t; while (t--) solve(); return 0; }
- 建立二叉树遍历求深度
- 通过中序和后序构建树,然后再层序输出
#include <bits/stdc++.h> #define int long long using namespace std; #define endl '\n' int po[35]; int ino[35]; vector<int>ans[50]; int dfs(int l1, int r1, int l2, int r2) { for (int i = l2; i <= r2; i++) { if (ino[i] == po[r1]) { int root = po[r1]; int lc = dfs(l1, l1 + i - l2 - 1, l2, i - 1) ; //递归左子树 int rc = dfs(l1 + i - l2, r1 - 1, i + 1, r2) ; //递归右子树 if (lc) ans[root].push_back(lc); if (rc) ans[root].push_back(rc); return root; } } return 0; } void solve() { int n; cin >> n; for (int i = 1; i <= n; i++) cin >> po[i]; for (int i = 1; i <= n; i++) cin >> ino[i]; dfs(1, n, 1, n); queue<int>q; q.push(po[n]); cout << po[n]; while (q.size()) { int t = q.front(); q.pop(); for (auto i : ans[t]) { q.push(i); cout << " " << i; } } } signed main() { int t = 1; // cin>>t; while (t--) solve(); return 0; }
- 找最大深度,以及最小且最长的路径
#include <bits/stdc++.h> using namespace std; vector<int>bd[10005]; bool vis[10005]; int maxx = -1; int root; map<int, int>d; //用来找根节点,根节点入度为0 vector<int>road; bool check; void dfslen(int x, int dep) { //递归找最大长度 if (bd[x].size() == 0) maxx = max(dep, maxx); for (auto t : bd[x]) dfslen(t, dep + 1); } bool dfs(int x,int dep) { if(dep==maxx) { return 1; } bool res=0; for(auto t:bd[x]) { if(dfs(t,dep+1)) { if(t<road[x]) road[x]=t; res=1; } } return res; } /* void dfs(int x,int dep) { if(dep==maxx) { check=1; return ; } check=0; for(auto t:bd[x]) { dfs(t,dep+1); if(check){ if(t<road[x]) road[x]=t; } } }*/ signed main() { int n; cin >> n; for (int i = 0; i < n; i++) { int x; cin >> x; while (x--) { int z; cin >> z; bd[i].push_back(z); d[z]++; } } //寻找根节点 for (int i = 0; i < n; i++) { if (d[i] == 0) { root = i; break; } } dfslen(root, 1); cout << maxx <<endl; road.resize(n); for(int i=0;i<n;i++) road[i]=1e9; dfs(root,1); int cur=root; cout<<root; while(road[cur]!=1e9) { cout<<" "<<road[cur]; cur=road[cur]; } }
- 通过后序遍历序列 建立层次遍历序列
#include <bits/stdc++.h> #define int long long using namespace std; #define endl '\n' int tree[100005]; int a[100005]; int p = 1; int n; void dfs(int x) { if (x <= n) { dfs(2 * x); dfs(2 * x + 1); tree[x] = a[p++]; } } void solve() { cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; dfs(1); cout << tree[1]; for (int i = 2; i <= n; i++) { cout << " " << tree[i]; } } signed main() { int t = 1; // cin>>t; while (t--) solve(); return 0; }
2.前序、中序、后序遍历的转换
给出了中序以后,给定前序或后序都可以确定唯一的一棵树。
不给出中序则无法确定。
P1827 [USACO3.4] 美国血统 American Heritage
- 这题给出前序和中序求后序
- 这题给出中序和后序求前序
posted on 2024-10-31 20:48 swj2529411658 阅读(14) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现