数据结构·树

树的特点

最小连通图

无环

有且只有 n − 1 n-1 n−1 条边

树的建立方式

顺序存储

只适用于满n叉树,完全n叉树

cpp 复制代码
void solve() {
	cin >> n;
	for (int i = 0; i<(1<<n); i++) {
		cin >> value[i + (1 << n)];
	}

结构体数组

使用整型存储父母和孩子的编号信息,结点的权值。

cpp 复制代码
typedef struct node {
	int w,l,r,f;
};
vector<node>nodes(109, node());

链式存储

比结构体数组存储更加灵活,不依赖结点编号,且给定输入,父子关系明确。

leetcode的给定输入格式

  • 使用结构体存储结点信息,使用指针的形式存储父母和孩子的信息
cpp 复制代码
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}

图的存储方式

树作为一种特殊的图,完全可以沿用图的存储方式


以下均为例题

遍历树的应用

对于遍历的理解,和递归三部曲的理解。

  • 226.翻转二叉树:后序遍历修改左右结点,注意需要设置中间值,不然会空指针异常。

101. 对称二叉树:操作两个结点进行遍历,使用后序遍历收集结果。

cpp 复制代码
    bool dfs(TreeNode*left,TreeNode*right){
        if(!left&&right)return false;
        if(left&&!right)return false;
        if(!left&&!right)return true;

        return left->val==right->val&&dfs(left->left,right->right)&&dfs(left->right,right->left);
    }
    bool isSymmetric(TreeNode* root) {
        if(!root)return true;
        return dfs(root->left,root->right);
    }
cpp 复制代码
    int dfs(TreeNode* root){
        if(!root)return 0;
        return max(dfs(root->left),dfs(root->right))+1;
    }
    int maxDepth(TreeNode* root) {
        return dfs(root);   
    }
  • 111.二叉树的最小深度:后序遍历,但是只有叶子结点才算深度,所以遍历空结点会干扰最后答案 ,干脆不遍历空结点,空结点设置为INT_MAX终止条件也改为叶子结点。y
cpp 复制代码
    int dfs(TreeNode*root){
        if(!root->left&&!root->right)return 1;
        int left=INT_MAX,right=INT_MAX;
        if(root->left)left=dfs(root->left);
        if(root->right)right=dfs(root->right);
        return min(left,right)+1;
    }
    int minDepth(TreeNode* root) {
        if(!root)return 0;
        return dfs(root);
    }

222.完全二叉树的节点个数:后序遍历或者BFS。

cpp 复制代码
    int dfs(TreeNode*root){
        if(!root)return 0;
        return dfs(root->left)+dfs(root->right)+1;
    }
    int countNodes(TreeNode* root) {
        return dfs(root);
    }
  • 110. 平衡二叉树本质是比较高度 。可以用pair<int,int>分别表示子树的高度和子树是否满足平衡二叉树,也可以用特殊值-1处理。
cpp 复制代码
    int dfs(TreeNode* root){
        if(!root)return 0;
        int left=dfs(root->left);
        int right=dfs(root->right);
    
        if(left==-1||right==-1)return -1;
        if(left-right>=2||right-left>=2){
            return -1;
        }

        return max(left,right)+1;
    }
    bool isBalanced(TreeNode* root) {
        if(dfs(root)!=-1)return true;
        return false;
    }
cpp 复制代码
    vector<string>res;
    void dfs(TreeNode* root,string s){
        if(!root)return;
        if(!root->left&&!root->right){
            res.push_back(s);
        }

        if(root->left){
            string tmp(s);
            tmp+="->";
            tmp+=to_string(root->left->val);
            dfs(root->left,tmp);
        }      

        if(root->right){
            string tmp(s);
            tmp+="->";
            tmp+=to_string(root->right->val);
            dfs(root->right,tmp);
        }

    }
    vector<string> binaryTreePaths(TreeNode* root) {
        string s;
        s+=to_string(root->val);
        dfs(root,s);
        return res;
    }
cpp 复制代码
    int dfs(TreeNode* root){
        if(!root)return 0;
        int value=0;
        if(root->left){
            if(!root->left->left&&!root->left->right){
                value+=root->left->val;
            }

        }

        return value+dfs(root->left)+dfs(root->right);
    }
    int sumOfLeftLeaves(TreeNode* root) {
        return dfs(root);
    }
cpp 复制代码
    int ans=0;
    int max_depth=0;
    void dfs(TreeNode* root,int depth){
        if(!root)return;
        if(!root->left&&!root->right){
            if(depth>max_depth){
                max_depth=depth;
                ans=root->val;
            }
        }
        dfs(root->left,depth+1);
        dfs(root->right,depth+1);
    }
    int findBottomLeftValue(TreeNode* root) {
        dfs(root,1);
        return ans;
    }
cpp 复制代码
    bool dfs(TreeNode* root,int sum,int targetSum){
        if(!root->left&&!root->right){
            if(sum==targetSum){
                return true;
            }
            return false;
        }
        bool left=false,right=false;
        if(root->left)left=dfs(root->left,sum+root->left->val,targetSum);
        if(root->right)right=dfs(root->right,sum+root->right->val,targetSum);
        return left||right;
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(!root)return false;
        return dfs(root,root->val,targetSum);
    }

*106.从中序与后序遍历序列构造二叉树:一道好题,从前序遍历建立树的模板。首先理解中序+后序怎么构造二叉树,然后利用前序的方式显示的建立每一个结点TreeNode*node=new TreeNode()。注意分割左右子树的数组时,迭代器是左闭右开[begin,end)的!

cpp 复制代码
    TreeNode*dfs(vector<int>& inorder,vector<int>& postorder){
        if(inorder.size()==0)return nullptr;
        if(inorder.size()==1){
            TreeNode*node=new TreeNode(inorder[0]);
            return node;
        }

        int value=postorder[postorder.size()-1];
        TreeNode*root=new TreeNode(value);

        int idx=-1;
        for(int i=0;i<inorder.size();i++){
            if(inorder[i]==value){idx=i;break;}
        }

        vector<int>inorder_left(inorder.begin(),inorder.begin()+idx);
        vector<int>inorder_right(inorder.begin()+idx+1,inorder.end());

        vector<int>postorder_left(postorder.begin(),postorder.begin()+idx);
        vector<int>postorder_right(postorder.begin()+idx,postorder.end()-1);

        root->left=dfs(inorder_left,postorder_left);
        root->right=dfs(inorder_right,postorder_right);
        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        return dfs(inorder,postorder);
    }
相关推荐
PHASELESS41125 分钟前
Java二叉树深度解析:结构、算法与应用实践指南
java·开发语言·数据结构·算法
祁同伟.29 分钟前
【数据结构 · 初阶】- 带头双向循环链表
数据结构·链表
学习2年半2 小时前
回溯算法:List 还是 ArrayList?一个深拷贝引发的思考
数据结构·算法·list
烁3472 小时前
每日一题(小白)暴力娱乐篇30
java·数据结构·算法·娱乐
Y.O.U..5 小时前
力扣HOT100——无重复字符的最长子字符串
数据结构·c++·算法·leetcode
Hanson Huang10 小时前
【数据结构】堆排序详细图解
java·数据结构·排序算法·堆排序
Susea&10 小时前
数据结构初阶:队列
c语言·开发语言·数据结构
序属秋秋秋11 小时前
算法基础_数据结构【单链表 + 双链表 + 栈 + 队列 + 单调栈 + 单调队列】
c语言·数据结构·c++·算法
purrrew13 小时前
【数据结构_5】链表(模拟实现以及leetcode上链表相关的题目)
数据结构·leetcode·链表
挺6的还13 小时前
4.B-树
数据结构·b树