详细题目请看牛客网重建二叉树
#include <iostream>
using namespace std;
struct BinaryTreeNode{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
BinaryTreeNode(int x) :m_nValue(x), m_pLeft(nullptr), m_pRight(nullptr) {}
};
void DestroyTree(BinaryTreeNode *pRoot) {
if (pRoot == nullptr)
return;
BinaryTreeNode *pLeft = pRoot->m_pLeft;
BinaryTreeNode *pRight = pRoot->m_pRight;
delete pRoot;
pRoot = nullptr;
DestroyTree(pLeft);
DestroyTree(pRight);
}
BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder,
int* startInorder, int* endInorder);
BinaryTreeNode* Construct(int* preorder, int* inorder, int length){
if(preorder == nullptr || inorder == nullptr || length <= 0)
return nullptr;
return ConstructCore(preorder, preorder+length-1, inorder, inorder+length-1);
}
BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder,
int* startInorder, int* endInorder){
int rootValue = startPreorder[0];
BinaryTreeNode* root = new BinaryTreeNode(rootValue);
if(startPreorder == endPreorder){
if(startInorder == endInorder && *startInorder == *startPreorder)
return root;
else{
cerr << "Invalid input!\n";
exit(1);
}
}
int* rootInorder = startInorder;
while(rootInorder < endInorder && *rootInorder != rootValue)
++rootInorder;
if(rootInorder == endInorder && *rootInorder != rootValue)
exit(1);
int leftLength = rootInorder - startInorder;
int* leftPreorderEnd = startPreorder + leftLength;
if(leftLength > 0){
root->m_pLeft = ConstructCore(startPreorder+1,leftPreorderEnd,startInorder,rootInorder-1);
}
if(leftLength < endPreorder - startPreorder){
root->m_pRight = ConstructCore(leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder);
}
return root;
}
void print(BinaryTreeNode* root){
cout << root->m_nValue << "\t";
}
void Inorder(BinaryTreeNode* root){
if(root != nullptr){
print(root);
Inorder(root->m_pLeft);
Inorder(root->m_pRight);
}
}
int main() {
const int length = 7;
int preorder[length] = {1,2,4,5,3,6,7};
int inorder[length] = {4,2,5,1,6,3,7};
/* vector<int> pre{1,2,4,5,3,6,7};
vector<int> vin{4,2,5,1,6,3,7};*/
BinaryTreeNode *newRoot = Construct(preorder, inorder,length);
Inorder(newRoot);
return 0;
}
刚开始刷,写的很吃力。又写了一遍,由于牛客网是vector输入,有了些改动,如下:
/*
* 重建二叉树
* */
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if(pre.empty() || vin.empty() || pre.size() != vin.size()) return nullptr;
TreeNode* pTree = new TreeNode(pre[0]);
vector<int> left_pre, right_pre, left_vin, right_vin;
vector<int>::iterator Elemet = find(vin.begin(),vin.end(),
pre[0]);
int position = 0;
if(Elemet != vin.end())
position = distance(vin.begin(),Elemet);
else return nullptr;
if(position >= 0 && position < pre.size()){
for (int i = 0; i < position; ++i) {
left_pre.emplace_back(pre[i+1]);
left_vin.emplace_back(vin[i]);
}
for (int i = position+1; i < pre.size(); ++i) {
right_pre.emplace_back(pre[i]);
right_vin.emplace_back(vin[i]);
}
}
pTree->left = reConstructBinaryTree(left_pre,left_vin);
pTree->right = reConstructBinaryTree(right_pre,right_vin);
return pTree;
}
};
void Print(TreeNode* head){
if(head != nullptr){
queue<TreeNode*> node;
node.emplace(head);
while(!node.empty()){
TreeNode* pNode = node.front();// no top() function.
node.pop();
cout << pNode->val << "\t";
if(pNode->left != nullptr) node.emplace(pNode->left);
if(pNode->right != nullptr) node.emplace(pNode->right);
}
}
}
int main() {
vector<int> preOder = {1,2,4,7,3,5,6,8};
vector<int> vinOder = {4,7,2,1,5,3,8,6};
Solution sl;
TreeNode* pHead;
pHead = sl.reConstructBinaryTree(preOder,vinOder);
Print(pHead);
return 0;
}
变种题:输入前序和中序,输出中序
思路是,就在上面的基础上建二叉树,后序输出即可;另一个看了讨论区,有人的思路是直接左子树+右子树+根节点输出即可,不需要重建二叉树。
思路一代码:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
struct TreeNode{
char val;
TreeNode* left;
TreeNode* right;
TreeNode(char x) : val(x), left(nullptr), right(nullptr) {}
};
vector<char> returnVector(vector<char> &pre, int begin, int end){
return vector<char>(pre.begin()+begin,pre.begin()+end);
}
TreeNode* reConstructTree(vector<char> pre, vector<char> vin){
if(pre.empty() || pre.size() != vin.size()) return nullptr;
TreeNode* pNode = new TreeNode(pre[0]);
vector<char>::iterator itr = find(vin.begin(),vin.end(),pre[0]);
int position = 0;
if(itr != vin.end()) position = distance(vin.begin(),itr);
else exit(1);
pNode->left = reConstructTree(returnVector(pre,1,position+1),returnVector(vin,0,position));
pNode->right = reConstructTree(returnVector(pre,position+1,pre.size()), returnVector(vin, position+1, vin.size()));
return pNode;
}
void Printpast(TreeNode* pNode){
if(pNode != nullptr){
Printpast(pNode->left);
Printpast(pNode->right);
cout << pNode->val;
}
}
int main(){
string s1, s2;
cin >> s1 >> s2;
if(s1.size() != s2.size()){
cerr << "Warning!";
exit(1);
}
vector<char> pre, vin;
for(int i = 0;i < s1.size();i++){
pre.emplace_back(s1[i]);
vin.emplace_back(s2[i]);
}
Printpast(reConstructTree(pre, vin));
}
思路二代码:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
struct TreeNode{
char val;
TreeNode* left;
TreeNode* right;
TreeNode(char x) : val(x), left(nullptr), right(nullptr){}
};
vector<char> returnVector(vector<char> &pre, int begin, int end){
return vector<char>(pre.begin()+begin,pre.begin()+end);
}
vector<char> PastOrder(vector<char> pre, vector<char> vin){
vector<char> result, result_left, result_right;
if(pre.empty() || pre.size() != vin.size() || vin.empty()) return result;
result.reserve(pre.size());
char rootValue = pre[0];
vector<char>::iterator itr = find(vin.begin(),vin.end(),pre[0]);
int position = 0;
if(itr != vin.end()) position = distance(vin.begin(),itr);
else exit(1);
result_left = PastOrder(returnVector(pre,1,position+1),returnVector(vin,0,position));
result_right = PastOrder(returnVector(pre,position+1,pre.size()), returnVector(vin, position+1, vin.size()));
result.insert(result.end(),result_left.begin(),result_left.end());
result.insert(result.end(),result_right.begin(),result_right.end());
result.push_back(rootValue);
return result;
}
int main(){
string s1, s2;
cin >> s1 >> s2;
if(s1.size() != s2.size()){
cerr << "Warning!";
exit(1);
}
vector<char> pre, vin;
for(int i = 0;i < s1.size();i++){
pre.emplace_back(s1[i]);
vin.emplace_back(s2[i]);
}
vector<char> result;
result = PastOrder(pre, vin);
for(const char& k : result){
cout << k;
}
}
本文深入探讨了如何使用前序遍历和中序遍历序列重建二叉树的算法,提供了详细的C++代码实现,并对比了两种不同的输出中序遍历结果的方法,一种是通过构建二叉树并进行后序遍历,另一种是直接利用输入序列计算得到结果。
363

被折叠的 条评论
为什么被折叠?



