【二叉树】由前序、中序遍历推后序遍历,由中序、后序遍历推前序遍历方法
学习资料
1.推断二叉树
2.AcWing 3598. 二叉树遍历(暑假每日一题2022)
1.函数对比
前序中序推后序
void dfs(string mid, string pre)
{
if (mid.size())
{
char root = pre[0];
int cur = mid.find(root);
dfs(mid.substr(0, cur), pre.substr(1, cur));
dfs(mid.substr(cur + 1), pre.substr(cur + 1));
cout << root;
}
}
中序后序推前序
注意:s.substr(a, len)
表示取字符串s
的下标a
开始,长度为len
的字符串
其中,第一个参数a
表示起始下标,第二参数len
表示长度。
void dfs(string mid, string last)
{
if (mid.size())
{
char root = last[last.size() - 1];
int cur = mid.find(root);
cout << root;
dfs(mid.substr(0, cur), last.substr(0, cur));
dfs(mid.substr(cur + 1), last.substr(cur, last.size() - cur - 1));
}
}
前序中序建树
char build(int il, int ir, int pl, int pr)
{
char root = pre[pl];
int k = pos[root];
if (il < k) l[root] = build(il, k - 1, pl + 1, pl + 1 + k - 1 - il);
if (ir > k) r[root] = build(k + 1, ir, pl + 1 + k - 1 - il + 1, pr);
return root;
}
中序后序建树
char build(int il, int ir, int pl, int pr)
{
char root = last[pr];
int k = pos[root];
if (il < k) l[root] = build(il, k - 1, pl, k - 1 - il + pl);
if (ir > k) r[root] = build(k + 1, ir, k - 1 - il + pl + 1, pr - 1);
return root;
}
2.由前序、中序推后序遍历
P1827 [USACO3.4] 美国血统 American Heritage
不建树写法
#include <iostream>
using namespace std;
void dfs(string mid, string pre)
{
if (mid.size())
{
char root = pre[0];
int cur = mid.find(root);
dfs(mid.substr(0, cur), pre.substr(1, cur));
dfs(mid.substr(cur + 1), pre.substr(cur + 1));
cout << root;
}
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
string mid, pre;
cin >> mid >> pre;
dfs(mid, pre);
return 0;
}
建树写法
#include <iostream>
#include <unordered_map>
using namespace std;
int n;
string mid, pre;
unordered_map<char, int> l, r, pos;
char build(int il, int ir, int pl, int pr)
{
char root = pre[pl];
int k = pos[root];
if (il < k) l[root] = build(il, k - 1, pl + 1, pl + 1 + k - 1 - il);
if (ir > k) r[root] = build(k + 1, ir, pl + 1 + k - 1 - il + 1, pr);
return root;
}
void dfs(char root)
{
if (l.count(root)) dfs(l[root]);
if (r.count(root)) dfs(r[root]);
cout << root;
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> mid >> pre;
n = mid.size();
for (int i = 0; i < n; i++) pos[mid[i]] = i;
char root = build(0, n - 1, 0, n - 1);
dfs(root);
return 0;
}
3598. 二叉树遍历
不建树写法
#include <iostream>
using namespace std;
void dfs(string mid, string pre)
{
if (mid.size())
{
char root = pre[0];
int cur = mid.find(root);
dfs(mid.substr(0, cur), pre.substr(1, cur));
dfs(mid.substr(cur + 1), pre.substr(cur + 1));
cout << root;
}
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
string mid, pre;
while (cin >> pre >> mid)
{
dfs(mid, pre);
cout << '\n';
}
return 0;
}
建树写法
#include <iostream>
#include <unordered_map>
using namespace std;
int n;
string mid, pre;
unordered_map<char, int> l, r, pos;
char build(int il, int ir, int pl, int pr)
{
char root = pre[pl];
int k = pos[root];
if (il < k) l[root] = build(il, k - 1, pl + 1, pl + 1 + k - 1 - il);
if (ir > k) r[root] = build(k + 1, ir, pl + 1 + k - 1 - il + 1, pr);
return root;
}
void dfs(char root)
{
if (l.count(root)) dfs(l[root]);
if (r.count(root)) dfs(r[root]);
cout << root;
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
while (cin >> pre >> mid)
{
n = mid.size();
pos.clear(), l.clear(), r.clear();
for (int i = 0; i < n; i++) pos[mid[i]] = i;
char root = build(0, n - 1, 0, n - 1);
dfs(root);
cout << '\n';
}
return 0;
}
1631. 后序遍历
建树写法
#include <iostream>
#include <unordered_map>
using namespace std;
const int N = 50010;
int n;
unordered_map<int, int> l, r, pos;
int pre[N], in[N], post[N], cnt;
int build(int il, int ir, int pl, int pr)
{
int root = pre[pl];
int k = pos[root];
if (il < k) l[root] = build(il, k - 1, pl + 1, pl + 1 + k - 1 - il);
if (ir > k) r[root] = build(k + 1, ir, pl + 1 + k - 1 - il + 1, pr);
return root;
}
void dfs(int root)
{
if (l.count(root)) dfs(l[root]);
if (r.count(root)) dfs(r[root]);
post[cnt++] = root;
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &pre[i]);
for (int i = 0; i < n; i++)
{
scanf("%d", &in[i]);
pos[in[i]] = i;
}
int root = build(0, n - 1, 0, n - 1);
dfs(root);
printf("%d\n", post[0]);
return 0;
}
3.由中序、后序推前序遍历
P1030 [NOIP 2001 普及组] 求先序排列
不建树写法
#include <iostream>
using namespace std;
void dfs(string mid, string last)
{
if (mid.size())
{
char root = last[last.size() - 1];
int cur = mid.find(root);
cout << root;
dfs(mid.substr(0, cur), last.substr(0, cur));
dfs(mid.substr(cur + 1), last.substr(cur, last.size() - cur - 1));
}
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
string mid, last;
cin >> mid >> last;
dfs(mid, last);
return 0;
}
建树写法
#include <iostream>
#include <unordered_map>
using namespace std;
string mid, last;
unordered_map<char, int> l, r, pos;
char build(int il, int ir, int pl, int pr)
{
char root = last[pr];
int k = pos[root];
if (il < k) l[root] = build(il, k - 1, pl, k - 1 - il + pl);
if (ir > k) r[root] = build(k + 1, ir, k - 1 - il + pl + 1, pr - 1);
return root;
}
void dfs(char root)
{
cout << root;
if (l.count(root)) dfs(l[root]);
if (r.count(root)) dfs(r[root]);
}
int main()
{
cin >> mid >> last;
int n = mid.size();
for (int i = 0; i < n; i++) pos[mid[i]] = i;
char root = build(0, n - 1, 0, n - 1);
dfs(root);
return 0;
}
4.由前序、中序构建二叉树
105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int n;
unordered_map<int, int> pos;
TreeNode* build(vector<int> &preorder, vector<int> &inorder, int il, int ir, int pl, int pr)
{
TreeNode* root = new TreeNode(preorder[pl]);
int k = pos[root->val];
if (il < k) //如果左子树存在,递归构建左子树
root->left = build(preorder, inorder, il, k - 1, pl + 1, pl + 1 + k - 1 - il);
if (ir > k) //如果右子树存在,递归构建右子树
root->right = build(preorder, inorder, k + 1, ir, pl + 1 + k - 1 - il + 1, pr);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
n = preorder.size();
for (int i = 0; i < n; i++) pos[inorder[i]] = i;
return build(preorder, inorder, 0, n - 1, 0, n - 1);
}
};
5.由中序、后序构建二叉树
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int n;
unordered_map<int, int> pos;
TreeNode* build(vector<int> &inorder, vector<int> &postorder, int il, int ir, int pl, int pr)
{
TreeNode* root = new TreeNode(postorder[pr]);
int k = pos[root->val];
if (il < k)
root->left = build(inorder, postorder, il, k - 1, pl, pl + k - 1 - il);
if (ir > k)
root->right = build(inorder, postorder, k + 1, ir, pl + k - 1 - il + 1, pr - 1);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
n = inorder.size();
for (int i = 0; i < n; i++) pos[inorder[i]] = i;
return build(inorder, postorder, 0, n - 1, 0, n - 1);
}
};
由中序后序推层序 1497. 树的遍历
先建树,再BFS求层序遍历序列
#include <iostream>
#include <queue>
#include <unordered_map>
using namespace std;
const int N = 40;
int n;
int mid[N], last[N];
unordered_map<int, int> l, r, pos;
int build(int il, int ir, int pl, int pr)
{
int root = last[pr]; // 后序遍历的最后一个结点是根结点
int k = pos[root]; // k是根结点在中序遍历中的下标
if (il < k) // 如果左子树存在
l[root] = build(il, k - 1, pl, pl + k - 1 - il);
if (k < ir) // 如果右子树存在
r[root] = build(k + 1, ir, pl + k - 1 - il + 1, pr - 1);
return root;
}
void bfs(int root)
{
queue<int> q;
q.push(root);
while (q.size())
{
int t = q.front();
q.pop();
cout << t << ' ';
if (l.count(t)) q.push(l[t]);
if (r.count(t)) q.push(r[t]);
}
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 0; i < n; i++) cin >> last[i];
for (int i = 0; i < n; i++)
{
cin >> mid[i];
pos[mid[i]] = i;
}
int root = build(0, n - 1, 0, n - 1);
bfs(root);
return 0;
}
分类:
二叉树
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验