二叉树系列(C++版本)

一、二叉树的三种遍历

1.前序遍历(中左右)

void PreOrder(TreeNode *root, vector<int> &v)
{
    if (root == nullptr)
            return;
        
    v.push_back(root->val);
    PreOrder(root->left, v);
    PreOrder(root->right, v);
}


vector<int> preorderTraversal(TreeNode* root) 
{
    vector<int> v;
    PreOrder(root, v);
    return v;
}

2.中序遍历(左中右)

void InOrder(TreeNode *root, vector<int> &v)
{
    if (root == nullptr)
        return;
        
    InOrder(root->left, v);
    v.push_back(root->val);
    InOrder(root->right, v);
}

vector<int> inorderTraversal(TreeNode* root) 
{
    vector<int> v;
    InOrder(root, v);
    return v;
}

3.后序遍历(左右中)

void PostOrder(TreeNode *root, vector<int> &v)
{
    if (root == nullptr)
        return;
        
    PostOrder(root->left, v);
    PostOrder(root->right, v);
    v.push_back(root->val);
}

vector<int> postorderTraversal(TreeNode* root) 
{
    vector<int> v;
    PostOrder(root, v);
    return v;
}

二、二叉树的最大深度(即根节点的高度)

//高度:某节点的叶子结点的层数,叶子结点高度为1
//深度:某节点到根结点的层数,根节点深度为1
//求根结点的高度,即为二叉树的最大深度

int getHeight(TreeNode *root)
{
    if (root == nullptr)
        return 0;

    //后序遍历求高度
    int leftH = getHeight(root->left);      //左子树的高度
    int rightH = getHeight(root->right);    //右子树的高度
    return 1 + max(leftH, rightH);  //子树的最大高度+1即为当前结点的最大高度
}

int maxDepth(TreeNode* root) 
{
    return getHeight(root);
}

三、二叉树的镜像

即从下往上依次交换左右孩子结点,后序遍历

TreeNode* Mirror(TreeNode* pRoot) 
{
    if (pRoot == nullptr)
        return nullptr;

    Mirror(pRoot->left);
    Mirror(pRoot->right);

    //交换左右节点
    TreeNode *temp = pRoot->left;
    pRoot->left = pRoot->right;
    pRoot->right = temp;

    return pRoot;
 }

四、判断二叉树

1.判断是否为二叉搜索树

        二叉搜索树满足每个节点的左子树上的所有节点均小于当前节点且右子树上的所有节点均大于当前节点。

    TreeNode *prev = nullptr;   //记录root的前结点
    bool isValidBST(TreeNode* root) 
    {
        // write code here
        if (root == nullptr)   
            return true;

        //中序遍历
        bool bleft = isValidBST(root->left);

        if (prev != nullptr && prev->val >= root->val)  //如果前结点val>=当前结点
            return false;
        prev = root;    //更新前结点

        bool bright = isValidBST(root->right);

        return bleft && bright;
    }

2.判断是否为完全二叉树

        完全二叉树的定义:若二叉树的深度为 h,除第 h 层外,其它各层的结点数都达到最大个数,第 h 层所有的叶子结点都连续集中在最左边,这就是完全二叉树。(第 h 层可能包含 [1~2h] 个节点)

    bool isCompleteTree(TreeNode* root) 
    {
        //思路:层序遍历,每层从左往右依次遍历
        //完全二叉树:遍历到的当前结点的之前结点都不为空,否则不是完全二叉树
        
        queue<TreeNode *> que;  //存储层序遍历的结点
        bool found = false;     //记录是否找到过空结点

        if (root != nullptr)
            que.push(root);

        while (!que.empty())
        {
            int size = que.size();  //记录当前层的结点数量
            while (size--)
            {
                TreeNode *node = que.front();   //记录队首结点
                que.pop();  //弹出队首结点

                if (node == nullptr)    //当前结点为空,更新标志位
                    found = true;
                else    //不空
                {
                    if (found)  //之前遍历过空结点,不是完全二叉树
                        return false;
                    //左右结点插入队尾
                    que.push(node->left);
                    que.push(node->right);
                }
            }
        }

        return true;
    }

3.判断是否为平衡二叉树

        平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

    //获取树的最大高度
    int getHeight(TreeNode *root)
    {
        if (root == nullptr)
            return 0;

        int leftH = getHeight(root->left);
        int rightH = getHeight(root->right);

        return 1 + max(leftH, rightH);
    }

    bool IsBalanced_Solution(TreeNode* pRoot) 
    {
        // write code here
        if (pRoot == nullptr)
            return true;

        int left = getHeight(pRoot->left);      //左子树的高度
        int right = getHeight(pRoot->right);    //右子树的高度

        if (abs(left - right) > 1)  //高度差>1,不是平衡二叉树
            return false;

        return IsBalanced_Solution(pRoot->left) && IsBalanced_Solution(pRoot->right);   //左右子树都为平衡二叉树,才满足条件
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值