代码随想录 -- 二叉树(未完待续)

因为lz考研复试可能优先回溯 动态规划 双指针,所以lz先进行这三样了!!!

二叉树递归遍历

前序遍历题目
后序遍历题目
中序遍历题目

#include<iostream>
#include <vector>

using namespace std;
struct TreeNode{
    int val;
    TreeNode*left;
    TreeNode*right;
    TreeNode():val(0),left(nullptr),right(nullptr){}
    TreeNode(int value):val(value),left(nullptr),right(nullptr){}
    TreeNode(int value,TreeNode*left,TreeNode*right):val(value),left(left),right(right){}
};
class BinaryTree{
public:
    // 先序遍历
    void preorder(TreeNode*root,vector<int>&result){
        if (!root)return;
        result.push_back(root->val);
        preorder(root->left,result);
        preorder(root->right,result);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int>result;
        preorder(root,result);
        return result;
    }

    // 后续遍历
    void postorder(TreeNode*root,vector<int>&result){
        if(!root)return;
        postorder(root->left,result);
        postorder(root->right,result);
        result.push_back(root->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int>result;
        postorder(root,result);
        return result;
    }

    //中序遍历
    void in(TreeNode*root,vector<int>&result){
        if(!root)return;
        in(root->left,result);
        result.push_back(root->val);
        in(root->right,result);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int>result;
        in(root,result);
        return result;
    }
};
int main(){
    TreeNode*t4 = new TreeNode(7);
    TreeNode*t3 = new TreeNode(8);
    TreeNode*t2 = new TreeNode(3,t3, nullptr);
    TreeNode*t1 = new TreeNode(1);
    TreeNode*t0 = new TreeNode(5,t2,t4);
    TreeNode*root = new TreeNode(10,t0,t1);
    BinaryTree bt;
    // 测试先序遍历
    auto v = bt.preorderTraversal(root);
    for (const auto &item: v) {
        cout<< item <<endl; 
    }
    delete root;
    delete t0;
    delete t1;
    delete t2;
    delete t3;
    delete t4;
    return 0;
}

二叉树迭代遍历

#include<iostream>
#include <vector>
#include<stack>
#include<algorithm>
using namespace std;
struct TreeNode{
    int val;
    TreeNode*left;
    TreeNode*right;
    TreeNode():val(0),left(nullptr),right(nullptr){}
    TreeNode(int value):val(value),left(nullptr),right(nullptr){}
    TreeNode(int value,TreeNode*left,TreeNode*right):val(value),left(left),right(right){}
};
class BinTree{
public:
    // 先序遍历
    /**
    * 栈是先入后出 先序遍历是 中左右
    * 入栈的时候先入右孩子 再入左孩子 这样出栈的时候可以先出左后出右
    * */
    vector<int> preorder(TreeNode*root){
        vector<int>result;//保存遍历之后的结果
        if (root== nullptr)return result;
        stack < TreeNode * > st; // 模拟递归的栈
        st.push(root);
        while (!st.empty()){
            auto r = st.top();
            st.pop();
            result.push_back(r->val);
            if (r->right)st.push(r->right);
            if (r->left)st.push(r->left);
        }
    return result;
    }
    // 后序遍历
    /**
    * 栈是先入后出 后序遍历是 左右中
    * 我们可以按照先序的 不过入栈的时候先入左孩子 再入右孩子
     * 这样的出来的是后序遍历的翻转
     */
    vector<int>postorder(TreeNode*root){
        stack<TreeNode*>st;
        vector<int>result;
        if (root== nullptr)return result;
        st.push(root);
        while (!st.empty()){
            auto r = st.top();
            st.pop();
            result.push_back(r->val);
            if (r->left)st.push(r->left);
            if (r->right)st.push(r->right);
        }
        reverse(result.begin(),result.end());
        return result;
    }

    //中序遍历
    vector<int> inorder(TreeNode*root){
        vector<int>result;
        if (root== nullptr)return result;
        TreeNode*cur = root;
        stack<TreeNode*>st;
        while (cur||!st.empty()){
            if (cur){// 指针来访问节点,访问到最底层
                st.push(cur);// 将访问的节点放进栈
                cur=cur->left;
            }else{
                cur = st.top();// 从栈里弹出的数据,就是要处理的数据
                st.pop();
                result.push_back(cur->val);//中
                cur=cur->right;//右
            }
        }
        return result;
    }
};
int main(){
    TreeNode*t4 = new TreeNode(7);
    TreeNode*t3 = new TreeNode(8);
    TreeNode*t2 = new TreeNode(3,t3, nullptr);
    TreeNode*t1 = new TreeNode(1);
    TreeNode*t0 = new TreeNode(5,t2,t4);
    TreeNode*root = new TreeNode(10,t0,t1);
    BinTree bt;
    auto v = bt.inorder(root);
    for (const auto &item: v) {
        cout<< item <<endl;
    }
    delete root;
    delete t0;
    delete t1;
    delete t2;
    delete t3;
    delete t4;
    return 0;
}

二叉统一的迭代遍历法

代码随想录网站

二叉树的层序遍历合集

二叉树层序遍历I

题目链接

描述

给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
在这里插入图片描述

题解

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>>result;
        if(root==nullptr)return result;
        queue<TreeNode*>q;
        q.push(root);
        while (!q.empty()){
            vector<int>vec;
            int size = q.size();
            for (int i = 0; i < size; ++i) {
                TreeNode* cur = q.front();
                vec.push_back(cur->val);
                q.pop();
                if (cur->left)q.push(cur->left);
                if (cur->right)q.push(cur->right);
            }
            result.push_back(vec);
        }
        return result;
    }
};

二叉树层序遍历II

题目链接

描述

给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
在这里插入图片描述

题解

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

二叉树的右视图

题目链接

描述

给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

在这里插入图片描述

题解

层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        vector<int>res;
        if (root == nullptr)return res;
        queue<TreeNode*>q;
        q.push(root);
        while (!q.empty()){
            int len = q.size();
            for (int i = 0; i < len; ++i) {
                auto t = q.front();
                q.pop();
                if(i==len-1)res.push_back(t->val);
                if (t->left)q.push(t->left);
                if (t->right)q.push(t->right);
            }
        }
        return res;
    }
};

二叉树的层平均值

题目链接

描述

给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。
在这里插入图片描述

题解

本题就是层序遍历的时候把一层求个总和在取一个均值。

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        vector<double>res;
        if (root== nullptr)return res;
        queue<TreeNode*>q;
        q.push(root);
        while (!q.empty()){
            const int len = q.size();
            double count=0;
            for (int i = 0; i < len; ++i) {
                auto t = q.front();
                q.pop();
                count+=t->val;
                if (t->left)q.push(t->left);
                if (t->right)q.push(t->right);
            }
            res.push_back(count/len);
        }
        return res;
    }
};

N叉树的层序遍历

题目链接

描述

给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。
在这里插入图片描述

题解

类似于二叉树的层序遍历

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        vector<vector<int>>res;
        if (root== nullptr)return res;
        queue<Node*>q;
        q.push(root);
        while (!q.empty()){
            vector<int>tmpRes;
            int len = q.size();
            for (int i = 0; i < len; ++i) {
                auto t=q.front();
                q.pop();
                tmpRes.push_back(t->val);
                for (int j = 0; j < t->children.size(); ++j)
                    q.push(t->children[j]);
            }
            res.push_back(tmpRes);
        }
        return res;
    }
};

在每个树行中找最大值

题目链接

描述

您需要在二叉树的每一行中找到最大的值。

在这里插入图片描述

题解

层序遍历,取每一层的最大值

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        vector<int>res;
        if (root== nullptr)return res;
        queue<TreeNode*>q;
        q.push(root);
        while (!q.empty()){
            int len = q.size();
            int maxNum=-2147483648;
            for (int i = 0; i < len; ++i) {
                auto t=q.front();
                q.pop();
                maxNum=(t->val>maxNum)?t->val:maxNum;
                if (t->left)q.push(t->left);
                if (t->right)q.push(t->right);
            }
            res.push_back(maxNum);
        }
        return res;
    }
};

填充每个节点的下一个右侧节点指针

题目链接

描述

给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。
在这里插入图片描述

题解

依旧是层序遍历,不过保存上次层序遍历的节点

class Solution {
public:
    Node* connect(Node* root) {
        if (root== nullptr)return root;
        queue<Node*>q;
        q.push(root);
        while (!q.empty()){
            int len = q.size();
            Node*tmp= nullptr;
            for (int i = 0; i < len; ++i) {
                Node*t=q.front();
                q.pop();
                if (tmp)tmp->next=t;
                if (i==len-1)t->next= nullptr;
                else{
                    tmp=t;
                }
                if (t->left)q.push(t->left);
                if (t->right)q.push(t->right);
            }
        }
        return root;
    }
};

填充每个节点的下一个右侧节点指针II

题目链接

描述

给定一个二叉树:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL 。

初始状态下,所有 next 指针都被设置为 NULL 。

题解

一样的逻辑

class Solution {
public:
    Node* connect(Node* root) {
        if (root== nullptr)return root;
        queue<Node*>q;
        q.push(root);
        while (!q.empty()){
            int len = q.size();
            Node*tmp= nullptr;
            for (int i = 0; i < len; ++i) {
                Node*t=q.front();
                q.pop();
                if (tmp)tmp->next=t;
                if (i==len-1)t->next= nullptr;
                else{
                    tmp=t;
                }
                if (t->left)q.push(t->left);
                if (t->right)q.push(t->right);
            }
        }
        return root;
    }
};

二叉树最大深度

题目链接

描述

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7],
在这里插入图片描述

题解:层序遍历

class Solution {
public:

    int maxDepth(TreeNode*root){
        if (root== nullptr)return 0;
        queue<TreeNode*>q;
        q.push(root);
        int depth=0;
        while (!q.empty()){
            int len = q.size();
            for (int i = 0; i < len; ++i) {
                auto node=q.front();
                q.pop();
                if (node->left)q.push(node->left);
                if (node->right)q.push(node->right);
            }
            ++depth;
        }
        return depth;
    }
};

题解:递归(深度优先搜索)

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (!root)return 0;
        int leftHigh = maxDepth(root->left);
        int rightHigh = maxDepth(root->right);
        return max(leftHigh,rightHigh)+1;
    }
};

二叉树的最小深度

题目链接

描述

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。

题解:层序遍历

只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点

class Solution {
public:
    int minDepth(TreeNode* root) {
        if (root== nullptr)return 0;
        queue<TreeNode*>q;
        int depth=0;
        q.push(root);
        while (!q.empty()){
            int len =q.size();
            ++depth;
            for (int i = 0; i < len; ++i) {
                TreeNode*node=q.front();
                q.pop();
                if (!node->left&&!node->right)return depth; 
                if (node->left)q.push(node->left);
                if (node->right)q.push(node->right);
            }
        }
        return depth;
    }   
};

题解:递归(深度优先)

class Solution {
public:
    int minDepth(TreeNode *root) {
        if (root == nullptr) {
            return 0;
        }

        if (root->left == nullptr && root->right == nullptr) {
            return 1;
        }

        int min_depth = INT_MAX;
        if (root->left != nullptr) {
            min_depth = min(minDepth(root->left), min_depth);
        }
        if (root->right != nullptr) {
            min_depth = min(minDepth(root->right), min_depth);
        }

        return min_depth + 1;
    }
};


翻转二叉树

题目链接

描述

翻转一棵二叉树。
在这里插入图片描述

题解:递归法

本题使用递归法 很是方便,我们定义一个实现翻转的函数,但root有左/右孩子的时候再翻转其左右孩子,直至root的左右孩子为空

class Solution {
public:
    void invert(TreeNode*root){
        if (root== nullptr)return;
        swap(root->left,root->right);
        invert(root->left);
        invert(root->right);
    }
    TreeNode* invertTree(TreeNode* root) {
        invert(root);
        return root;
    }
};

题解:迭代法

前序遍历和后续遍历途中进行翻转,下面的代码使用的是前序遍历

class Solution {
public:
    TreeNode*invertTree(TreeNode*root){
        if (root== nullptr)return root;
        stack<TreeNode*>st;
        st.push(root);
        while (!st.empty()){
            auto node=st.top();
            st.pop();
            swap(node->left,node->right);
            if (node->right)st.push(node->right);
            if (node->left)st.push(node->left);
        }
        return root;
    }
};

题解:层序遍历

class Solution {
public:
    TreeNode*invertTree(TreeNode*root){
          if (root== nullptr)return root;
        queue<TreeNode*>q;
        q.push(root);
        while (!q.empty()){
            auto node=q.front();
            q.pop();
            swap(node->left,node->right);
            if (node->left)q.push(node->left);
            if (node->right)q.push(node->right);
        }
        return root;
    }
};

对称二叉树

题目链接

描述

给定一个二叉树,检查它是否是镜像对称的。

在这里插入图片描述

题解:递归

class Solution {
public:
    bool compare(TreeNode*left,TreeNode*right){
        if (left&&!right)return false;
        else if(!left&&right)return false;
        else if (!left&&!right)return true;
        else if(left->val!=right->val)return false;

        bool leftFlag = compare(left->left,right->right);
        bool rightFlag = compare(left->right,right->left);

        return leftFlag&&rightFlag;
    }
    bool isSymmetric(TreeNode* root) {
        if (!root)return true;
        return compare(root->left,root->right);
    }
};

题解:迭代法

class Solution {
public:
    bool isSymmetric(TreeNode*root) {
        if (!root)return true;
        queue<TreeNode*>q;
        q.push(root->left);
        q.push(root->right);
        while (!q.empty()){
            auto n1=q.front();q.pop();
            auto n2=q.front();q.pop();
            if (!n1&&!n2)continue;
            if (n1&&!n2||!n1&&n2||n1->val!=n2->val)return false;
            q.push(n1->left);
            q.push(n2->right);
            q.push(n1->right);
            q.push(n2->left);
        }
        return true;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值