二叉树专题 -- 持续更新

二叉树题目总结归纳:
二叉树结构:

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

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

1求二叉树的最大深度

// v1 深度遍历
int find_max_depth_v1(TreeNode* root)
{
    if(!root)
        return 0;
    int left = find_max_depth_v1(root->left);
    int right = find_max_depth_v1(root->right);
    return 1 + (left > right ? left : right);
}


// v2 宽度优先
int find_max_depth_v2(TreeNode* root)
{
    if(!root)
        return 0;
    queue<TreeNode*> q;
    q.push(root);
    int depth = 0;
    while(!q.empty())
    {
        depth ++;
        for(int i = 0; i < q.size(); i++)
        {
            TreeNode* pNode = q.front();
            q.pop();
            if(pNode->left)
                q.push(pNode->left);
            if(pNode->right)
                q.push(pNode->right);
        }
    }
    return depth;
}

2.求二叉树的最小深度

// v1 深度优先
//这里与最大深度不同的地方是,需要考虑二叉树仅有一边子树的情况,
//若直接套用最大子树的思路,取左右子树中的最小值,那么最小值永远是0
int find_min_depth_v1(TreeNode* root)
{
    if(!root)
        return 0;
    if(!root->left)
        return 1 + find_min_depth_v1(root->right);
    if(!root->right)
        return 1 + find_min_depth_v1(root->left);
    return 1 + (left < right ? left : right);
}


// v2 宽度优先
int find_min_depth_v2(TreeNode* root)
{
    if(!root)
        return 0;
    queue<TreeNode*> q;
    q.push(root);
    int depth = 0;
    while(!q.empty())
    {
        depth ++;
        for(int i = 0; i < q.size(); i++)
        {
            TreeNode* pNode = q.front();
            q.pop();
            if(!pNode->left && !pNode->right)
                return depth;
            if(pNode->left)
                q.push(pNode->left);
            if(pNode->right)
                q.push(pNode->right);
        }
    }
    return depth;
}

3.求二叉树中节点的个数

int get_num_node(TreeNode* root)
{
    if(!root)
        return 0;
    int left = get_num_node(root->left);
    int right = get_num_node(root->right);
    return left + right + 1;
}

4.求二叉树中叶子节点的个数

int get_leaf_node(TreeNode* root)
{
    if(!root)
        return 0;
    if(!root->left && !root->right)
        return 1;
    int left = get_leaf_node(root->left);
    int right = get_leaf_node(root->right);
    return left + right;
}

5.求二叉树中第 k 层节点的个数

int get_kth_node(TreeNode* root, int k)
{
    if(!root || k < 1)
        return 0;
    if(k == 1)
        return 1;
    int left = get_kth_node(root->left, k-1);
    int right = get_kth_node(root->right, k-1);
    return left + right;
}

6.二叉树的第K大个节点

//中序遍历
TreeNode* kthNode(TreeNode* root, int k)
{
    if(!root || k < 1)
        return NULL;
    return kthNodeCore();
}


TreeNode* kthNodeCore(TreeNode* root)
{
    TreeNode* res = NULL;
    if(root->left)
        res = kthNodeCore(root->left);
    if(!res)
    {
        if(k == 1)
            res = root;
        k --;
    }
    if(!res && root->right)
        res = kthNodeCore(root->right);
    return res;
}

7.判断二叉树是否是平衡二叉树

bool IsBalanceTree(TreeNode* root)
{
    if(!root)
        return true;
    return max_depth(root) != -1;
}


int max_depth(TreeNode* root)
{
    if(!root)
        return 0;
    int left = max_depth(root->left);
    int right = max_depth(root->right);
    if(left == -1 || right == -1 || abs(left - right) > 1)
        return -1;
    return 1 + (left > right ? left : right);
}

8.判断二叉树是否是完全二叉树

/判断一棵树是否是完全二叉树,首先要知道什仫是完全二叉树?
//完全二叉树就是除最后一层外,每一层上的结点数均达到最大值;在最后一层上只缺少右边的若干结点。
bool IsCompleteTree(TreeNode* root)
{
    if(!root)
        return false;
    queue<TreeNode*> q;
    q.push(root);
    TreeNode* cur = q.front();
    while(cur)
    {
        q.push(root->left);
        q.push(root->right);
        q.pop();
        cur = q.front();    
    }
    while(!q.empty())
    {
        if(q.front())
            return false;
        q.pop();
    }
    return true;
}

9.两个二叉树是否完全相同

// 前序遍历
bool IsSameTree(TreeNode* root1, TreeNode* root2)
{
    if(!root1 && !root2)
        return true;
    if(!root1 || !root2)
        return false;
    if(root1->val != root2->val)
        return false;
    bool left = IsSameTree(root1->left, root2->left);
    bool right = IsSameTree(root1->right, root2->right);
    return left && right;
}

10.两个二叉树是否互为镜像

bool IsMirrorTree(TreeNode* root1, TreeNode* root2)
{
    if(!root1 && !root2)
        return true;
    if(!root1 || !root2)
        return false;
    if(root1->val != root2->val)
        return false;
    return IsMirrorTree(root1->left, root2->right) && \
            IsMirrorTree(root1->right, root2->left);
}

11.翻转或者镜像二叉树

void MirrorTree(TreeNode* root)
{
    if(!root)
        return ;
    if(!root->left && !root->right)
        return ;
    TreeNode* tmp = root->left;
    root->left = root->right;
    root->right = tmp;
    MirrorTree(root->left);
    MirrorTree(root->right);
}

12.求两个二叉树的最低公共祖先节点

// 利用二叉树的递增属性
TreeNode* getLastCommonParent(TreeNode* root, TreeNode* node1, TreeNode* node2)
{
    if(!root || !node1 || !node2)
        return NULL;
    if(finNode(root->left, node1))
    {
        if(findNode(root->right, node2))
            return root;
        else
            return getLastCommonParent(root->left, node1, node2);
    }
    else{
        if(findNode(root->left, node2))
            return root;
        else
            return getLastCommonParent(root->right, node1, node2);
    }
}
// 节点是否在子树内
bool findNode(TreeNode* root, TreeNode* node)
{
    if(!root || !node)
        return false;
    if(root->val == node->val && root->left == node->left \
            && root->right == node->right)
        return true;
    bool res = findNode(root->left);
    if(!res)
        res = findNode(root->right);
    return res;       
}

13.前序遍历

vector<int> preOrder(TreeNode* root)
{
    vector<int> result;
    if(!root)
        return result;
    preOrderCore(root, result);
    return result;
}

void preOrderCore(TreeNode* root, vector<int>& result)
{
    if(!root)
        return ;
    result.push_back(root->eval);
    if(root->left)
        preOrderCore(root->left, result);
    if(root->left)
        preOrderCore(root->right, result);
}

14.中序遍历

vector<int> midOrder(TreeNode* root)
{
    vector<int> result;
    if(!root)
        return result;
    midOrderCore(root, result);
    return result;
}

void midOrderCore(TreeNode* root, vector<int>& result)
{
    if(root->left)
        midOrderCore(root->left, result);
    if(!root)
        result.push_back(root->val);
    if(root->right)
        midOrderCore(root->right, result);
}

15.后序遍历

vector<int> postOrder(TreeNode* root)
{
    vector<int> result;
    if(!root)
        return result;
    postOrderCore(root, result);
    return result;
}

void postOrderCore(TreeNode* root, vector<int>& result)
{
    if(root->left)
        postOrderCore(root->left, result);
    if(root->right)
        postOrderCore(root->right, result);
    if(!root)
        result.push_back(root->val);
}

16.输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树

TreeNode* reConstructTree(vector<int> pre, vector<int> vin)
{
    int len1 = pre.size();
    int len2 = vin.size();
    if(pre.empty() || vin.empty() || len1 == len2)
        return NULL;
    return reConstructTreeCore(pre, vin, 0, len1 - 1, 0, len2 - 1);
}

TreeNode* reConstructTreeCore(vector<int> pre, vector<int> vin, int begin1, int end1, \
                              int begin2, int end2)
{
    int val = pre[begin1];
    TreeNode* root = new TreeNode(val);
    if(begin1 == end1)
        return root;
    int ind = begin2;
    while(vin[ind] != val)
        ind ++;
    if(ind > begin2)
        root->left = reConstructTreeCore(pre, vin, begin1 + 1, begin1 + ind - begin2, \
                            begin2, ind - 1);
    if(ind < end2)
        root->right = reConstructTreeCore(pre, vin, begin1 + ind - begin2 + 1, end1, \
                                          ind + 1, end2);
    return root;
}

未完待续。。。20190611晚!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值