树形练习题

树形练习题

学习算法的第一步就是树形联系题目。这几乎是所有问题的根基。这里将一些树形题目进行了分享,内容主要包括
-树的遍历
-求树的高度
-求树的最近公共祖先
-打印树的某个路径
废话不说了,现在就上代码:

/*************************************************************************
    > 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值