二叉樹的一些基本操做

數據結構的一些知識好久沒碰了,忘得差很少了都,來回顧總結一下,本篇先寫一下二叉樹相關的一些操做。node

二叉樹定義

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

二叉樹的建立

經過輸入先序二叉樹序列建立二叉樹,用'#'字符表明空節點。c++

//經過先序輸入建立二叉樹
TreeNode* CreateTreeByInput()
{
    char ch;
    std::cin >> ch;
    if (ch == '#')
        return NULL;//輸入#表示建立結束
    TreeNode* root = new TreeNode(ch);
    root->left = CreateTreeByInput();
    root->right = CreateTreeByInput();
    return root;
}

二叉樹的遍歷

先序、中序、後序三種基本遍歷方式。數據結構

//先序遍歷
void PreOrder(TreeNode* root)
{
    if (root == NULL)return;
    std::cout << (char)root->val << ' ';
    PreOrder(root->left);
    PreOrder(root->right);
}
//中序遍歷
void InOrder(TreeNode* root)
{
    if (root == NULL)return;
    PreOrder(root->left);
    std::cout << (char)root->val << ' ';
    PreOrder(root->right);
}
//後序遍歷
void PostOrder(TreeNode* root)
{
    if (root == NULL)return;
    std::cout << (char)root->val << ' ';
    PreOrder(root->left);
    PreOrder(root->right);
}

還有一種層次遍歷方式,從上往下逐層遍歷,須要藉助隊列實現,每次將父結點出隊,子結點進隊便可。code

//層次遍歷
void levelOrder(TreeNode* root)
{
    if (root == NULL)return;
    queue<TreeNode*> q;
    q.push(root);
    while (!q.empty())
    {
        TreeNode* now = q.front();
        cout << (char)now->val << ' ';
        if (now->left != NULL)q.push(now->left);
        if (now->right != NULL)q.push(now->right);
        q.pop();
    }
}

LeetCode上一道題目:https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/
要求獲得自底向上的層次遍歷序列,只須要先按層次遍歷獲得序列,而後用頭插法插入最終集合便可。索引

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>> result;
        if(root==NULL)return result;
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty())
        {
            vector<int> level;
            int cnt=q.size();
            for(int i=0;i<cnt;i++)
            {
                TreeNode* node=q.front();
                q.pop();
                level.push_back(node->val);
                if(node->left!=NULL)q.push(node->left);
                if(node->right!=NULL)q.push(node->right);
            }
            result.insert(result.begin(),level);
        }
        return result;
    }
};

二叉樹序列化與反序列化

序列化就是指將二叉樹轉換成一個序列(好比字符串),反序列化就是將轉換的序列還原成二叉樹。隊列

序列化

沒啥好說的,按照先序遍歷依次寫入字符串。ci

//序列化二叉樹(先序),結果保存在str中
void Serialize(TreeNode* root, std::string& str)
{
    if (root == NULL)
    {
        str += "#";
        return;
    }
    str += (char)root->val;
    Serialize(root->left, str);
    Serialize(root->right, str);
}

反序列化

反序列化就是按照先序遍歷建立的同時,用index索引來從字符串中讀取當前結點對應字符。leetcode

//反序列化方法(先序)
TreeNode* Deserialize(const std::string str, int& index)
{
    if (str == "" && index >= str.size())return NULL;
    if (str[index] == '#')
    {
        index++;
        return NULL;
    }
    TreeNode* root = new TreeNode(str[index++]);
    root->left = Deserialize(str, index);
    root->right = Deserialize(str, index);
    return root;
}

//調用反序列化
    string str = "akjl#####";
    int index = 0;
    TreeNode* root=Deserialize(str, index);

求二叉樹最大深度(層數)

//二叉樹最大深度
int MaxDepth(TreeNode* root)
{
    if (root == NULL)return 0;
    return max(MaxDepth(root->left), MaxDepth(root->right)) + 1;
}

二叉樹全部路徑

題目:https://leetcode-cn.com/problems/binary-tree-paths/
深搜完事,碰到葉子結點就說明找到一條路徑,加入結果集合,不然就繼續搜。字符串

class Solution {
public:
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> res;
        dfs(root,"",res);
        return res;
    }

    void dfs(TreeNode* root,string str,vector<string> &res)
    {
        if(root!=NULL)
        {
            str+=to_string(root->val);
            if(root->left==NULL&&root->right==NULL)
            {
                res.push_back(str);return;
            }
            dfs(root->left,str+"->",res);
            dfs(root->right,str+"->",res);
        }
    }
};
相關文章
相關標籤/搜索