
树
这里描述关于树的算法,二叉树,二叉搜索树,平衡树,B树,红黑树。
哎呦,帅小伙哦
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
B树的代码实现
B树的原理在这篇博客https://blog.youkuaiyun.com/xiaoan08133192/article/details/115622370中进行了介绍,这里是B树的代码实现。B树的插入和删除函数,在遍历的时候都是使用不回溯的方法,插入操作在对a结点插入数据的时,已经保证了a的关键字个数小于2*M - 1,删除操作在对a结点删除数据的时,已经保证了a的关键字个数大于M - 1。如何保证这一点是代码的精髓//M为B树的最小度#define M 2typedef struct btree_node原创 2021-04-16 11:57:13 · 1049 阅读 · 2 评论 -
LeetCode 104 二叉树的最大深度
分析 方法一:递归的方法,定义一个变量dep用来统计二叉树的最大深度,遍历到当前节点的深度是_dep,dep = _dep > dep ? _dep : dep 方法二:BFS,直接统计二叉树有多少层,代码如下:代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * ...原创 2020-07-28 20:52:49 · 105 阅读 · 0 评论 -
红黑树原理及代码实现
#include <iostream>using namespace std;enum Color{Red, Black};template <typename T>struct rbNode{ T data; Color color; rbNode<T>* left; rbNode<T>* right; rbNode<...原创 2020-05-04 18:51:11 · 258 阅读 · 0 评论 -
平衡二叉树的建立查考插入删除操作
如果二叉排序树的左、右子树的高度之差的绝对值不超过1,这样的排序二叉树称为平衡二叉树,它的平均查找长度达到O(log2n)。 为了避免树的高度增长过快,降低二叉排序树的性能,我们规定在插入和删除二叉树结点时,要保证任意结点的左、右子树高度差的绝对值不超过1。这样的二叉树称为平衡二叉树。 平衡二叉树可定义为它或是一棵空树,或者是具有下列性质的二叉树:它的左子树...原创 2020-04-26 18:15:01 · 659 阅读 · 0 评论 -
二叉树的创建与各种遍历
1,二叉树是一种树形结构,其特点是每个节点至多只有两个子树,并且二叉树是有序树,左右子树不能颠倒。2,二叉树和度为2的树有什么区别? 1)度为2的树至少有3个结点,而二叉树可以为空 2)度为2的有序树的孩子结点的左右次序是相对于另一个孩子而言的,如果某个结点只有一个孩子结点,这个孩子结点就无须区分其左右次序,而二叉树无论其孩子树是否是2,均需确定其左右次序。3,...原创 2020-04-24 18:31:22 · 208 阅读 · 0 评论 -
LeetCode 993 二叉树的堂兄弟节点
分析二叉树的层次遍历,使用节点指针记录x,y的父节点,在遍历完每一层时进行判断。代码class Solution {public: bool isCousins(TreeNode* root, int x, int y) { queue<TreeNode*> que; if(root != nullptr){ que.push(root); } while(!que.empty()){.原创 2021-05-17 22:05:59 · 104 阅读 · 0 评论 -
LeetCode 1609 奇偶树
分析层次遍历,思路比较简单,注意细节即可代码class Solution {public: bool isEvenOddTree(TreeNode* root) { queue<TreeNode*> que; if(nullptr != root) que.push(root); TreeNode* temp = nullptr; int depth = 0; int pre = INT_MIN.原创 2021-05-15 11:08:51 · 96 阅读 · 0 评论 -
LeetCode 剑指Offer 26 树的子结构
class Solution {public: bool isSubStructure(TreeNode* A, TreeNode* B) { if(B == nullptr) return false;//空树不算子结构 if(A == nullptr) return false; return judge(A, B) || isSubStructure(A -> left, B) || isSubStructure(A -> rig原创 2021-05-13 12:00:22 · 85 阅读 · 0 评论 -
LeetCode 面试题04.10 检查子树
分析递归,judge来判断t1和t2是否相同。代码class Solution {public: bool checkSubTree(TreeNode* t1, TreeNode* t2) { if(t2 == nullptr) return true; if(t1 == nullptr) return false; return judge(t1, t2) || checkSubTree(t1 -> left, t2) || ch.原创 2021-05-13 11:44:44 · 89 阅读 · 0 评论 -
LeetCode 863 二叉树中所有距离为K的结点
分析分为两步,一步是查找target下面满足条件的数据。另一步是查找target上面满足条件的数据。第二步困难一些。dfs函数返回的是root节点到target节点的距离。如果 target 在 root左子树中,假设 target 距离 root 的距离为 L+1,找出右子树中距离 target 节点 K - L - 1 距离的所有节点加入答案。代码class Solution { public: int K; vector<int> distanceK.原创 2021-05-12 11:25:39 · 130 阅读 · 0 评论 -
LeetCode 563 二叉树的坡度
分析简单后序遍历,锻炼递归思维代码class Solution {private: int ans; public: int findTilt(TreeNode* root) { traverse(root); return ans; } void traverse(TreeNode* root){ if(nullptr == root) return; traverse(root -&g.原创 2021-05-11 15:08:42 · 116 阅读 · 0 评论 -
LeetCode 543 二叉树的直径
分析后序遍历,调用完traverse函数后,每个节点的val值的含义是以该节点为根的树的最大高度-1。锻炼递归思维代码class Solution {private: int ans; public: int diameterOfBinaryTree(TreeNode* root) { traverse(root); return ans; } void traverse(TreeNode* root){ .原创 2021-05-11 14:49:02 · 82 阅读 · 0 评论 -
LeetCode 508 出现次数最多的子树元素和
分析后序遍历,思路不难。代码class Solution {public: vector<int> findFrequentTreeSum(TreeNode* root) { traverse(root); vector<int> vec; vector<int> ans; traverse1(root, vec); sort(vec.begin(), vec.end()).原创 2021-05-09 15:00:49 · 95 阅读 · 0 评论 -
LeetCode 437 路径总和
分析用一个数组记录一下数据,采用后序遍历代码class Solution {private: int num; public: int pathSum(TreeNode* root, int sum) { vector<int> vec; traverse(root, sum, vec); return num; } void traverse(TreeNode* root, i.原创 2021-05-09 11:53:08 · 167 阅读 · 0 评论 -
LeetCode 501 二叉搜索树中的众数
分析中序遍历,顺便使用几个变量进行信息记录代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nul.原创 2021-05-08 17:51:03 · 98 阅读 · 1 评论 -
LeetCode 951 翻转等价二叉树
分析简单递归问题代码class Solution {public: bool flipEquiv(TreeNode* root1, TreeNode* root2) { if(root1 == nullptr && root2 == nullptr) return true; if((root1 == nullptr && root2 != nullptr) || (root1 != nullptr && r.原创 2021-04-28 21:35:25 · 97 阅读 · 0 评论 -
LeetCode 623 在二叉树中插入一行
分析层次遍历,使用一个变量d来记录是否到达需要出入结点的位置代码class Solution {public: TreeNode* addOneRow(TreeNode* root, int val, int depth) { TreeNode* node = nullptr; if(depth == 1){ node = new TreeNode(val); node -> left.原创 2021-04-27 16:32:23 · 86 阅读 · 0 评论 -
LeetCode 669 修建二叉搜索树
分析简单递归问题。代码class Solution {public: TreeNode* trimBST(TreeNode* root, int low, int high) { if(root == nullptr) return nullptr; if(root -> val < low) return trimBST(root -> right, low, high); if(root -> .原创 2021-04-27 15:55:09 · 112 阅读 · 0 评论 -
LeetCode 814 二叉树剪枝
分析简单后序遍历代码class Solution {public: TreeNode* pruneTree(TreeNode* root) { if(root == nullptr) return root; root -> left = pruneTree(root -> left); root -> right = pruneTree(root -> right); if(root ->.原创 2021-04-26 21:00:50 · 78 阅读 · 0 评论 -
LeetCode 1008 前序遍历构造二叉搜索树
分析简单递归遍历代码class Solution {public: TreeNode* bstFromPreorder(vector<int>& preorder) { TreeNode* root = nullptr; int size = preorder.size(); for(int i = 0; i < size; i++){ root = insert(root, preorde.原创 2021-04-25 11:05:11 · 154 阅读 · 0 评论 -
LeetCode 889 根据前序和后序遍历构造二叉树
分析思路不难,主要是确定边界。代码class Solution {public: TreeNode* constructFromPrePost(vector<int>& pre, vector<int>& post) { return build(pre, 0, pre.size() - 1, post, 0, post.size() - 1); } TreeNode* build(const vector.原创 2021-04-24 12:09:59 · 82 阅读 · 0 评论 -
LeetCode 341 扁平化嵌套列表迭代器
分析这道题是一道设计题,思路参考了labuladong中写的文章,自己想不出来。值得复习。。。代码class NestedIterator {private: vector<int> it; int index; public: NestedIterator(vector<NestedInteger> &nestedList) { //将列表打平到vector中,可以把嵌套列表看成一颗N叉树 vector&l.原创 2021-04-19 23:01:29 · 130 阅读 · 0 评论 -
LeetCode 515 在每个树行中找最大值
分析简单层次遍历代码class Solution {public: vector<int> largestValues(TreeNode* root) { int max = 0; int size = 0; vector<int> ans; queue<TreeNode*> que; TreeNode* temp = nullptr; if(nullptr.原创 2021-04-18 12:57:44 · 87 阅读 · 0 评论 -
LeetCode 450 删除二叉搜索树中的节点
分析二叉搜索树的递归框架如下:TreeNode* BST(TreeNode* root, int target){ if(root != nullptr) return root; if(root -> val == target){ //找到目标,该做什么 }else if(root -> val < target){ root -> right = BST(root -> right, target); }else{ root -> lef.原创 2021-04-16 16:35:42 · 94 阅读 · 0 评论 -
LeetCode 538 把二叉树转换成累加树
分析BST相关的问题,不是利用BST做小右大的特性提升算法效率,就是利用中序遍历的特性满足题目要求。这道题目我们利用中序遍历,但是是按照右中左的顺序访问的,而且会在外部维护一个sum来记录遍历到当前结点的和。代码如下:代码class Solution {public: int sum;//记录和 TreeNode* convertBST(TreeNode* root) { sum = 0; traverse(root); retur.原创 2021-04-15 09:59:04 · 90 阅读 · 0 评论 -
LeetCode 652 寻找重复的子树
分析二叉树的题目需要判断使用前序中序还是后序,怎么判断呢?这就需要根据题意,思考一个二叉树结点需要做什么。比如这道题目,需要注意两点:1)以我为根的这棵二叉树(子树)长啥样2)以其他结点为根的子树长什么样子**根据树的序列化和反序列化,已经知道,如果唯一的确定一棵二叉树,这里我们使用后序遍历。**只需要将每棵二叉树的序列化后的s放入到一个map中即可(在放入之前,看一看有没有其他的树和要放入的树相同)。代码class Solution {public: map<string,.原创 2021-04-14 23:48:18 · 156 阅读 · 0 评论 -
LeetCode 297 二叉树的序列化和反序列化
分析需要注意的是,一般情况下,单单前序遍历是不能还原二叉树结构的,因为缺少空指针的信息,至少要得到前中后序遍历中的两种才能还原二叉树。但是我们可以记录空指针的位置,这样就可以唯一确定一棵二叉树。后序遍历也可以完成,但是需要注意的是,中序遍历是不可以的,因为反序列化要求先拿到root节点,中序遍历做不到这一点。这道题目除了前后序遍历可以解决,层次遍历也是可以解决的。这里不写代码了。代码//前序遍历代码class Codec {public: // Encodes a tree to a.原创 2021-04-14 16:40:27 · 112 阅读 · 0 评论 -
LeetCode 783二叉搜索树节点最小距离
分析因为是二叉搜索树,所以满足条件的结点肯定是中序遍历后相邻的结点,递归地进行中序遍历,使用pre记录前面结点的值,这样遍历完整棵树就可以得到任意结点最小距离。代码class Solution {public: int min; int minDiffInBST(TreeNode* root) { min = INT_MAX; int pre = -100001; traverse(root, pre); retu.原创 2021-04-13 15:48:52 · 116 阅读 · 0 评论 -
LeetCode 222 完全二叉树的节点个数
分析如果是一棵普通的二叉树,返回树中结点个数的代码如下:int countNodes(TreeNode* root){ if(null == root) return 0; return 1 + countNodes(root -> left) + countNodes(root -> right);}如果是一棵满二叉树,结点总数就和树的高度呈指数关系,时间复杂度是O(logN * logN)( 思考为什么):int countNodes(TreeNode* root){.原创 2021-04-13 13:19:35 · 105 阅读 · 0 评论 -
B树的原理
1,B树类似于红黑树,但它们在降低磁盘I/O操作数方面要更好一些,许多数据库系统使用B树或者B树的变种来存储信息。B树与红黑树的不同在于B树的节点可以有很多孩子,从数个到数千个。B树类似于红黑树,每个含有n个结点的B树的高度为O(lgn)。然而,一棵B树的严格高度可能比一棵红黑树的高度要小许多,这是因为它的分之因子,也就是说表示高度的对数的底数可以非常大。因此我们可以使用B树在时间O(lgn)内完成一些动态集合的操作。2,B树的定义一棵B树T是具有以下性质的有根树:1)每个结点x有下面属性:x.n当前原创 2021-04-12 23:27:19 · 872 阅读 · 0 评论 -
LeetCode 114 二叉树展开为链表
分析这个问题可以分为两步,1)将root的左子树和右子树拉平 2)将root的右子树接到左子树的下方,然后将整个左子树作为整个右子树。锻炼递归代码void flatten(TreeNode* root){ if(nullptr == root) return; //将左右子树拉成一条链表 flatten(root -> left); flatten(root -> right); TreeNode* .原创 2021-04-10 16:28:29 · 90 阅读 · 0 评论 -
LeetCode 116 填充每个节点的下一个右侧节点指针
分析这道题也可以使用层次遍历,递归的代码更简洁。递归算法的关键要明确函数的定义,相信这个定义,而不要跳进递归细节。代码class Solution {public: Node* connect(Node* root) { if(nullptr == root) return nullptr; connectTwo(root -> left, root -> right); return root; } //连接.原创 2021-04-10 16:11:24 · 102 阅读 · 0 评论 -
LeetCode 322 零钱兑换
分析这是一道完全背包的题目,但是我们这里只使用暴力法求解,目的是锻炼递归思维。暴力法其实是N叉树的后序遍历。代码class Solution {public: int coinChange(vector<int>& coins, int amount) { return dp(coins, coins.size(),amount); } int dp(vector<int>& coins, in.原创 2021-04-09 15:11:30 · 93 阅读 · 0 评论 -
LeetCode 235 二叉搜索树的最近公共祖先
分析利用二叉搜索树的特性,如果(root -> val - p -> val) * (root -> val - q -> val) <= 0,说明p和q节点在root的两次,否则在root的一侧,当然也可以使用236题那种后序遍历存储祖先节点的方法,但是性能肯定没有这钟方法高。代码class Solution {public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeN.原创 2021-04-08 16:56:40 · 90 阅读 · 0 评论 -
LeetCode 236 二叉树的最近公共祖先
分析postTraverse函数的作用是找到根节点到指定结点的路径,找根节点到指定结点的路径使用后序遍历,但是需要注意的是,当root结点是其父节点的左孩子,并且root已经是需要查找的节点或者需要查找的节点已经找的时候,就不再需要遍历右子树了。postTraverse函数使用判断vec是否是空来达到这一目的。postTraverse这个函数是解决类似问题的基础。锻炼递归思维。代码/** * Definition for a binary tree node. * struct TreeNod.原创 2021-04-08 16:30:22 · 145 阅读 · 0 评论 -
LeetCode 257 二叉树的所有路径
分析树的遍历,当root是叶子结点的时候,就把路径s加入到vector中,否则深搜。代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int .原创 2021-04-08 15:39:25 · 85 阅读 · 0 评论 -
LeetCode 429 N叉树的层次遍历
分析和二叉树的层次遍历相同,需要学习的是如何保证外层循环没遍历一次是访问一层。这里我们使用一个变量来记录每层的个数。代码/*// Definition for a Node.class Node {public: int val; vector<Node*> children; Node() {} Node(int _val) { val = _val; } Node(int _val, vector<N.原创 2021-04-05 21:13:35 · 87 阅读 · 0 评论 -
剑指 Offer 32 从上到下打印二叉树
分析层次遍历,注意怎么保证队列que中留的是树中一层上的值。代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public.原创 2021-04-04 16:57:14 · 79 阅读 · 0 评论 -
LeetCode 230 二叉搜索树中第k小元素
分析中序遍历得到递增数组,取第k个元素。时间复杂度O(N),空间复杂度O(N),其中N为数组的个数。可以使复杂度达到O(K),这就需要把递归函数优化一下,把K传进去,访问到第K个最小元素的时候返回。代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(.原创 2021-04-03 11:45:35 · 138 阅读 · 0 评论 -
LeetCode 199 二叉树的右视图
分析层次遍历,这个题可以学习到的是,我们可以引入一个变量来使队列里面的元素在遍历下一层之初只有上一层的节点。代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * T.原创 2021-04-03 11:18:31 · 80 阅读 · 0 评论