构建二叉树
构建二叉树
本文图文并茂讲解从前序遍历、中序续遍历构建二叉树或者从后序遍历、中序续遍历又或者从前序遍历、后序续遍历构建二叉树的原理,比附上相关的习题。
注意:
将提供以下图文链接供大家理解:
图文链接:
飞书图解链接🎉🎉🎉
密码:86N2619&
1. 从前序遍历、中序续遍历构建二叉树
题目一
AC代码,展开查看
/**
* 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:
unordered_map<int, int> pos;
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
for(int i = 0; i < inorder.size(); i ++ ) pos[inorder[i]] = i;
return build(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
}
TreeNode* build(vector<int>& preorder, vector<int>& inorder, int pl, int pr, int il, int ir){
if(pl > pr) return nullptr;
auto root = new TreeNode(preorder[pl]);
int k = pos[root -> val];
root -> left = build(preorder, inorder, pl + 1, k - il + pl, il, k - 1);
root -> right = build(preorder, inorder, k - il + pl + 1, pr, k + 1, ir);
return root;
}
};
2. 从后序遍历、中序续遍历构建二叉树
题目一
AC代码,展开查看
/**
* 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:
unordered_map<int, int> pos;
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
for(int i = 0; i < inorder.size(); i ++ ) pos[inorder[i]] = i;
return build(inorder, postorder, 0, inorder.size() - 1, 0, postorder.size() - 1);
}
TreeNode* build(vector<int>& inorder, vector<int>& postorder, int il, int ir, int pl, int pr){
if(il > ir) return nullptr;
auto root = new TreeNode(postorder[pr]);
int k = pos[root -> val];
root -> left = build(inorder, postorder, il, k - 1, pl, pl + k - il - 1);
root -> right = build(inorder, postorder, k + 1, ir, pl + k - il, pr - 1);
return root;
}
};
题目二
前置知识
- 数组模拟二叉树
- 数组大小为: 将此二叉树转化为完全二叉树的节点的数目 + 1
- 注意: 节点必须从索引1开始
示例代码:
AC代码,展开查看
#include<bits/stdc++.h>
using namespace std;
const int N = 9;
int a[N]; // 根节点在a[1]
void proOrder(int index){
if(index > N) return;
cout << a[index] << endl;
proOrder(2 * index);
proOrder(2 * index + 1);
}
int main(){
for(int i = 1; i <= N; i ++ ) a[i] = i;
proOrder(1);
return 0;
}
/*
运行结果
1
2
4
8
9
5
3
6
7
*/
- 结构体二叉树
示例代码:
AC代码,展开查看
#include<bits/stdc++.h>
using namespace std;
const int N = 9;
struct Node{
int val;
Node* left;
Node* right;
Node(int val){
this -> val = val;
}
~Node(){
cout << "回收掉的val值为: " << this -> val << "\n";
}
};
Node* buildTree(int val){
if(val > N) return nullptr;
Node* root = new Node(val);
root -> left = buildTree(2 * val);
root -> right = buildTree(2 * val + 1);
return root;
}
void proOrder(Node* root){
if(!root) return;
cout << "前序: " << root -> val << "\n";
proOrder(root -> left);
proOrder(root -> right);
}
void inOrder(Node* root){
if(!root) return;
inOrder(root -> left);
cout << "中序: " << root -> val << "\n";
inOrder(root -> right);
}
void postOrder(Node* root){
if(!root) return;
postOrder(root -> left);
postOrder(root -> right);
delete root;
}
int main(){
auto root = buildTree(1);
proOrder(root);
inOrder(root);
postOrder(root);
return 0;
}
/*
运行结果
1
2
4
8
9
5
3
6
7
*/
解题思路:
- 根据后序遍历和中序遍历构建出二叉树,然后进行一次前序遍历
AC代码,展开查看
#include<bits/stdc++.h>
using namespace std;
const int N = 10; // 长度小于等于8
unordered_map<char, int> pos;
struct Node{
char val;
Node* left;
Node* right;
Node(int val){
this -> val = val;
}
~Node(){
cout << "回收掉的val值为: " << this -> val << "\n";
}
};
Node* build(string& inorder, string& postorder, int il, int ir, int pl, int pr);
Node* buildTree(string& inorder, string& postorder) {
for(int i = 0; i < inorder.size(); i ++ ) pos[inorder[i]] = i;
return build(inorder, postorder, 0, inorder.size() - 1, 0, postorder.size() - 1);
}
Node* build(string& inorder, string& postorder, int il, int ir, int pl, int pr){
if(il > ir) return nullptr;
auto root = new Node(postorder[pr]);
int k = pos[root -> val];
root -> left = build(inorder, postorder, il, k - 1, pl, pl + k - il - 1);
root -> right = build(inorder, postorder, k + 1, ir, pl + k - il, pr - 1);
return root;
}
void proOrder(Node* root){
if(!root) return;
cout << root -> val;
proOrder(root -> left);
proOrder(root -> right);
}
void postOrder(Node* root){
if(!root) return;
postOrder(root -> left);
postOrder(root -> right);
delete root;
}
int main(){
string inStr, postStr;
cin >> inStr >> postStr;
auto root = buildTree(inStr, postStr);
proOrder(root);
postOrder(root);
return 0;
}
- 根据后序遍历和中序遍历输出前序遍历
AC代码,展开查看
#include<bits/stdc++.h>
using namespace std;
const int N = 10;
// 中序 后序
char inStr[N], postStr[N];
unordered_map<char, int> pos;
void dfs(char inStr[], char postStr[], int il, int ir, int pl, int pr){
if(ir >= il){
char c = postStr[pr]; // 根节点, 按序输出根节点即为前序遍历
printf("%c", c);
int k = pos[c];
dfs(inStr, postStr, il, k - 1, pl, k - il - 1 + pl);
dfs(inStr, postStr, k + 1, ir, k - il + pl, pr - 1);
}
}
int main(){
scanf("%s%s", inStr, postStr);
int n = strlen(inStr);
for(int i = 0; i < n; i ++ ) pos[inStr[i]] = i;
dfs(inStr, postStr, 0, n - 1, 0, n - 1);
return 0;
}
3. 从前序遍历、后序续遍历构建二叉树
题目一
AC代码,展开查看
/**
* 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:
unordered_map<int, int> pos;
TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {
for(int i = 0; i < postorder.size(); i ++ ) pos[postorder[i]] = i;
return build(preorder, postorder, 0, preorder.size() - 1, 0, postorder.size() - 1);
}
// postorder -> afterorder
TreeNode* build(vector<int>& preorder, vector<int>& postorder, int pl, int pr, int al, int ar){
if(pl > pr) return nullptr;
auto root = new TreeNode(preorder[pl]);
if(pl == pr) return root;
int k = pos[preorder[pl + 1]];
root -> left = build(preorder, postorder, pl + 1, k - al + pl + 1, al, k);
root -> right = build(preorder, postorder, k - al + pl + 2, pr, k + 1, ar);
return root;
}
};
海纳百川,有容乃大!如果文章有什么不足之处,还请大神们评论区留言指出,我在此表达感谢🥰!若大家喜欢我的作品,欢迎点赞、收藏、打赏🎉🎉🎉!