树形练习题
学习算法的第一步就是树形联系题目。这几乎是所有问题的根基。这里将一些树形题目进行了分享,内容主要包括
-树的遍历
-求树的高度
-求树的最近公共祖先
-打印树的某个路径
废话不说了,现在就上代码:
/*************************************************************************
> File Name: path.cpp
> Author: Yuji CAO
> Mail: yujicao@amazon.com
> Created Time: 2016年08月13日 星期六 09时05分37秒
> 没有写过的已经会的程序,就是不会写
************************************************************************/
#include<iostream>
#include<vector>
#include<unordered_map>
#include<unordered_set>
#include<sstream>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<utility>
#include<algorithm>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int val):val(val),left(nullptr),right(nullptr){}
};
namespace tree {
/*
1
|\
2 3
| |\
4 5 6
1,2,3,4,#,5,6,#,#,#,#,#,#
*/
static TreeNode* buildTree(const string& dataInput) {
//split
vector<int> dataVec;
int pre = -1;
string data = dataInput;
data += ",";
for (int i = 0; i < data.size(); ++i) {
if (data[i] == ',') {
string s = data.substr(pre + 1, i - 1 - pre);
pre = i;
int a = numeric_limits<int>::min();
if (s != "#") {
a = atoi(s.c_str());
}
dataVec.push_back(a);
}
}
if (dataVec.empty()) {
return nullptr;
}
TreeNode* root = new TreeNode(dataVec[0]);
queue<TreeNode*> q;
q.push(root);
int i = 1;
while (i < dataVec.size()) {
queue<TreeNode*> qq;
while (!q.empty()) {
TreeNode* cur = q.front();
q.pop();
int a = dataVec[i++];
if (a == numeric_limits<int>::min()) {
cur->left = nullptr;
} else {
cur->left = new TreeNode(a);
qq.push(cur->left);
}
a = dataVec[i++];
if (a == numeric_limits<int>::min()) {
cur->right = nullptr;
} else {
cur->right = new TreeNode(a);
qq.push(cur->right);
}
}
q = qq;
}
return root;
}
class PrintPath {
public:
/*
1
|\
2 3
| |\
4 5 6
1,2,(4)
1,(2)
1,3,5
1,3,(5)
1,3,6
1,3,(6)
1,(3)
(1)
*/
vector<int> print(int node, const TreeNode* const root) {
stack<const TreeNode*> s;
const TreeNode* cur = root;
const TreeNode* pre = nullptr;
while (!s.empty() || cur != nullptr) {
while(cur != nullptr) {
s.push(cur);
if (cur->val == node) {
return mkresult(s);
}
cur = cur->left;
}
if (!s.empty()) {
const TreeNode* t = s.top();
if (pre == t->right || nullptr == t->right) {
pre = t;
s.pop();
cur = nullptr;
} else {
cur = t->right;
}
}
}
vector<int> ans;
return ans;
}
private:
vector<int> mkresult(stack<const TreeNode*>& s) {
vector<int> ans;
stack<const TreeNode*> rs;
while (!s.empty()) {
rs.push(s.top());
s.pop();
}
while(!rs.empty()) {
ans.push_back(rs.top()->val);
rs.pop();
}
return ans;
}
};
class ClosestParent {
public:
int get(int f, int s, const TreeNode* const root) {
bool hasF = false;
bool hasS = false;
auto ans = getInner(f, s, root, hasF, hasS);
return ans->val;
}
private:
const TreeNode* getInner(int f, int s, const TreeNode* const root, bool& hasF, bool& hasS) {
if (root == nullptr) {
return nullptr;
}
if (root->val == f) {
hasF = true;
}
if (root->val == s) {
hasS = true;
}
bool hasF1 = false;
bool hasS1 = false;
const TreeNode* l = getInner(f, s, root->left, hasF1, hasS1);
if (hasF1) hasF = true;
if (hasS1) hasS = true;
if (hasF1 && hasS1) {
return l;
}
bool hasF2 = false;
bool hasS2 = false;
const TreeNode* r = getInner(f, s, root->right, hasF2, hasS2);
if (hasF2) hasF = true;
if (hasS2) hasS = true;
if (hasF2 && hasS2) {
return r;
}
if (hasF && hasS)
return root;
return nullptr;
}
};
class Height {
public:
/* 1
* |\
* 2 3
* | |\
* 4 5 6
*
* 1,1->[1,1],[2,2],{[4,3]}; nullptr,3
* nullptr,3->[1,1],{[2,2]}; nullptr,2
* nullptr,2->{[1,1]}; 3,1
* 3,1->[3,2],{[5,3]}; nullptr,3
* nullptr,1->{[3,2]}; 6,2
* nullptr,1->{[6,3]}; nullptr,3
*/
int get1(const TreeNode* const root) {
stack<pair<const TreeNode*, int> > s;
const TreeNode* cur = root;
int ans = 0;
int height = 0;
while (!s.empty() || cur != nullptr) {
while(cur != nullptr) {
height += 1;
s.push({cur, height});
cur = cur->left;
}
if (!s.empty()) {
pair<const TreeNode*, int> t = s.top();
s.pop();
cur = t.first->right;
height = t.second;
}
ans = max(height, ans) ;
}
return ans;
}
int get2(const TreeNode* const root) {
if (root == nullptr) {
return 0;
}
return 1 + max(get2(root->left), get2(root->right));
}
};
class Visit {
public:
vector<int> postOrder(const TreeNode* const root, int i = 1) {
vector<int> ans;
if (i == 1)
cout<<"1->",postOrder1(root, ans);
else
cout<<"2->",postOrder2(root, ans);
return ans;
}
vector<int> inOrder(const TreeNode* const root, int i = 1) {
vector<int> ans;
if (i == 1)
cout<<"1->",inOrder1(root, ans);
else
cout<<"2->",inOrder2(root, ans);
return ans;
}
vector<vector<string> > level(const TreeNode* const root) {
vector<vector<string> > ans;
level1(root, ans);
return ans;
}
private:
void level1(const TreeNode* const root, vector<vector<string> >& ans) {
queue<const TreeNode*> q;
q.push(root);
vector<string> ansEle;
stringstream ss;
ss<<root->val;
ansEle.push_back(ss.str());
ans.push_back(ansEle);
while (!q.empty()) {
int i = q.size();
vector<string> ansEle;
while (i > 0) {
const TreeNode* t = q.front();
q.pop();
if (t->left) {
stringstream ss;
ss<<t->left->val;
ansEle.push_back(ss.str());
q.push(t->left);
} else {
ansEle.push_back("#");
}
if (t->right) {
stringstream ss;
ss<<t->right->val;
ansEle.push_back(ss.str());
q.push(t->right);
} else {
ansEle.push_back("#");
}
i -= 1;
}
ans.push_back(ansEle);
}
}
void level2(const TreeNode* const root, vector<vector<int> >& ans) {
queue<const TreeNode*> q;
q.push(root);
while (!q.empty()) {
int i = q.size();
vector<int> ansEle;
while (i > 0) {
const TreeNode* t = q.front();
ansEle.push_back(t->val);
q.pop();
if (t->left) {
q.push(t->left);
}
if (t->right) {
q.push(t->right);
}
i -= 1;
}
ans.push_back(ansEle);
}
}
void inOrder1(const TreeNode* const root, vector<int>& ans) {
if (root == nullptr) {
return;
}
inOrder1(root->left, ans);
ans.push_back(root->val);
inOrder1(root->right, ans);
}
void inOrder2(const TreeNode* const root, vector<int>& ans) {
stack<const TreeNode*> s;
const TreeNode* cur = root;
while (!s.empty() || cur != nullptr) {
while(cur != nullptr) {
s.push(cur);
cur = cur->left;
}
if (!s.empty()) {
const TreeNode* t = s.top();
ans.push_back(t->val);
s.pop();
cur = t->right;
}
}
}
void postOrder1(const TreeNode* const root, vector<int>& ans) {
if (root == nullptr) {
return;
}
postOrder1(root->left, ans);
postOrder1(root->right, ans);
ans.push_back(root->val);
}
void postOrder2(const TreeNode* const root, vector<int>& ans) {
stack<const TreeNode*> s;
const TreeNode* cur = root;
const TreeNode* pre = nullptr;
while (!s.empty() || cur != nullptr) {
while (cur != nullptr) {
s.push(cur);
cur = cur->left;
}
if (!s.empty()) {
const TreeNode* t = s.top();
if (t->right == nullptr || t->right == pre) {
pre = t;
ans.push_back(t->val);
s.pop();
cur = nullptr;
} else {
cur = t->right;
}
}
}
}
};
};
int main() {
TreeNode* root = tree::buildTree("1,2,3,4,#,5,6,#,#,#,#,#,#");
tree::Visit visit;
auto ans = visit.postOrder(root, 2);
for (auto ele : ans) {
cout<<ele<<",";
}
cout<<endl;
auto ans1 = visit.inOrder(root, 2);
for (auto ele : ans1) {
cout<<ele<<",";
}
cout<<endl;
auto ans2 = visit.level(root);
for (auto ele : ans2) {
cout<<"[";
for (auto eleInner : ele) {
cout<<eleInner<<",";
}
cout<<"]"<<endl;
}
tree::Height height;
auto ans3 = height.get1(root);
cout<<"Height:\t"<<ans3<<endl;
auto ans4 = height.get2(root);
cout<<"Height:\t"<<ans4<<endl;
tree::ClosestParent cp;
cout<<"3,6->"<<cp.get(3, 6 , root)<<endl;
cout<<"2,6->"<<cp.get(2, 6 , root)<<endl;
tree::PrintPath pp;
auto ans5 = pp.print(5, root);
for (auto ele : ans5) {
cout<<ele<<",";
}
cout<<endl;
return 0;
}