树(Tree)解题总结
定义
树是一种抽象数据类型(ADT)或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由 n(n>0) 个有限节点组成一个具有层次关系的集合。。
二叉搜索树(Binary Search Tree,简称 BST)是一种很常用的的二叉树。它的定义是:一个二叉树中,任意节点的值要大于等于左子树所有节点的值,且要小于等于右边子树的所有节点的值。
如下就是一个符合定义的 BST:
算法模板
void traverse(TreeNode root) {
// root 需要做什么?在这做。
// 其他的不用 root 操心,抛给框架
traverse(root.left);
traverse(root.right);
}
在二叉树框架之上,扩展出一套 BST 遍历框架:
void BST(TreeNode root, int target) {
if (root.val == target)
// 找到目标,做点什么
if (root.val < target)
BST(root.right, target);
if (root.val > target)
BST(root.left, target);
}
前序遍历(递归):
List<int> preorder(TreeNode root) {
List<int> ans = new List<int>();
if (root == null) {
return ans;
}
ans.Add(root.Val);
ans.AddRange(preorder(root.Left));
ans.AddRange(preorder(root.Right));
return ans;
}
中序遍历(递归):
List<int> inorder(TreeNode root) {
List<int> ans = new List<int>();
if (root == null) {
return ans;
}
ans.AddRange(preorder(root.Left));
ans.Add(root.Val);
ans.AddRange(preorder(root.Right));
return ans;
}
后序遍历(递归):
List<int> postorder(TreeNode root) {
List<int> ans = new List<int>();
if (root == null) {
return ans;
}
ans.AddRange(preorder(root.Left));
ans.AddRange(preorder(root.Right));
ans.Add(root.Val);
return ans;
}
前序遍历(迭代/栈):
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res; //保存结果
stack<TreeNode*> call; //调用栈
if(root!=nullptr) call.push(root); //首先介入root节点
while(!call.empty()){
TreeNode *t = call.top();
call.pop(); //访问过的节点弹出
if(t!=nullptr){
if(t->right) call.push(t->right); //右节点先压栈,最后处理
if(t->left) call.push(t->left);
call.push(t); //当前节点重新压栈(留着以后处理),因为先序遍历所以最后压栈
call.push(nullptr); //在当前节点之前加入一个空节点表示已经访问过了
}else{ //空节点表示之前已经访问过了,现在需要处理除了递归之外的内容
res.push_back(call.top()->val); //call.top()是nullptr之前压栈的一个节点,也就是上面call.push(t)中的那个t
call.pop(); //处理完了,第二次弹出节点(彻底从栈中移除)
}
}
return res;
}
};
中序遍历(迭代/栈):
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> call;
if(root!=nullptr) call.push(root);
while(!call.empty()){
TreeNode *t = call.top();
call.pop();
if(t!=nullptr){
if(t->right) call.push(t->right);
call.push(t); //在左节点之前重新插入该节点,以便在左节点之后处理(访问值)
call.push(nullptr); //nullptr跟随t插入,标识已经访问过,还没有被处理
if(t->left) call.push(t->left);
}else{
res.push_back(call.top()->val);
call.pop();
}
}
return res;
}
};
后序遍历(迭代/栈):
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> call;
if(root!=nullptr) call.push(root);
while(!call.empty()){
TreeNode *t = call.top();
call.pop();
if(t!=nullptr){
call.push(t); //在右节点之前重新插入该节点,以便在最后处理(访问值)
call.push(nullptr); //nullptr跟随t插入,标识已经访问过,还没有被处理
if(t->right) call.push(t->right);
if(t->left) call.push(t->left);
}else{
res.push_back(call.top()->val);
call.pop();
}
}
return res;
}
};
要点
- 二叉树算法设计的总路线:把当前节点要做的事做好,其他的交给递归框架,不用当前节点操心。
- 如果当前节点会对下面的子节点有整体影响,可以通过辅助函数增长参数列表,借助参数传递信息。
- 删除二叉搜索树的节点有三种情况:
- A 恰好是末端节点,两个子节点都为空,那么它可以当场去世了
- A 只有一个非空子节点,那么它要让这个孩子接替自己的位置。
- A 有两个子节点,麻烦了,为了不破坏 BST 的性质,A 必须找到左子树中最大的那个节点,或者右子树中最小的那个节点来接替自己。
实战题目
1.树的遍历
2.树的操作
参考资料
树(Tree)解题总结的更多相关文章
- 【九度OJ】题目1176:树查找 解题报告
[九度OJ]题目1176:树查找 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1176 题目描述: 有一棵树,输出某一深度的所有节点 ...
- 【LeetCode】297. Serialize and Deserialize Binary Tree 解题报告(Python)
[LeetCode]297. Serialize and Deserialize Binary Tree 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode ...
- 【LeetCode】331. Verify Preorder Serialization of a Binary Tree 解题报告(Python)
[LeetCode]331. Verify Preorder Serialization of a Binary Tree 解题报告(Python) 标签: LeetCode 题目地址:https:/ ...
- 树(tree)
树(tree)[题目描述]从前在森林里面有一棵很大的树,树上住着很多小动物.树上有
- JS--插件: 树Tree 开发与实现
日常在Web项目开发时,经常会碰到树形架构数据的显示,从数据库中获取数据,并且显示成树形.为了方便,我们可以写一个javascript的一个跨浏览器树控件,后续可以重复使用.本节分享一个自己开发的JS ...
- 【LeetCode】863. All Nodes Distance K in Binary Tree 解题报告(Python)
[LeetCode]863. All Nodes Distance K in Binary Tree 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http ...
- 【LeetCode】109. Convert Sorted List to Binary Search Tree 解题报告(Python)
[LeetCode]109. Convert Sorted List to Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id ...
- 【LeetCode】236. Lowest Common Ancestor of a Binary Tree 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 【LeetCode】99. Recover Binary Search Tree 解题报告(Python)
[LeetCode]99. Recover Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/p ...
- 【LeetCode】662. Maximum Width of Binary Tree 解题报告(Python)
[LeetCode]662. Maximum Width of Binary Tree 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.co ...
随机推荐
- luogu P6087 [JSOI2015]送礼物 二分 单调队列 决策单调性
LINK:送礼物 原本想了一个 \(nlog^2\)的做法 然后由于线段树常数过大 T到30. 以为这道题卡\(log^2\)没想到真的有神仙写\(log^2\)的过了 是我常数大了 抱歉. 能过的\ ...
- Spark Streaming高吞吐、高可靠的一些优化
分享一些Spark Streaming在使用中关于高吞吐和高可靠的优化. 目录 1. 高吞吐的优化方式 1.1 更改序列化的方式 1.2 修改Receiver接受到的数据的存储级别 1.3 广播配置变 ...
- Meow 攻击会删除不安全(开放的)的Elasticsearch(及MongoDB) 索引,然后建一堆以Meow结尾的奇奇怪怪的索引(如:m3egspncll-meow)
07月29日,早上照例一来,先连接Elasticsearch查看日志[禁止转载,by @CoderBaby],结果,咦,什么情况,相关索引被删除了,产生了一堆以Meow开头的奇奇怪怪的索引,如下图: ...
- Python 超简单 提取音乐高潮(附批量提取)
很多时候我们想提取某首歌的副歌部分(俗称 高潮部分),只能手动直接卡点剪切,但是对于大批量的获取就很头疼,如何解决? 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后 ...
- pageHelper使用时的注意点
1 在pom.xml中导入相关的依赖(注意版本问题,报错十有八九是因为版本问题) <dependency> <groupId>com.github.pagehelper< ...
- Java 图书管理项目
思路总结: 1.使用空布局 2.构造方法里写初始打开的界面 3.return 意思是 "否则" 代替else if,一切归于平静 4.连接数据库时 db=new database ...
- The Involution Principle
目录 Catalan Paths Vandermonde Determinant The Pfaffian Catalan Paths 从 \((0,0)\) 走到 \((n,n)\), 每次只能向上 ...
- Java中访问控制修饰符的详解和示例——Java学习
Java中的四个访问控制修饰符 简述 在Java中共有四个: public -- 对外部完全可见 protected -- 对本包和所有子类可见 默认(不需要修饰符)-- 对本包可见 private ...
- LeetCode 646 最长数对链详解
题目描述 给出 n 个数对. 在每一个数对中,第一个数字总是比第二个数字小. 现在,我们定义一种跟随关系,当且仅当 b < c 时,数对(c, d) 才可以跟在 (a, b) 后面.我们用这种形 ...
- VS Code 黑宝书背后的故事
自开售以来,<Visual Studio Code 权威指南>就受到了许多读者朋友的青睐.在京东和当当两大平台上,都分别取得了不错的绩: 当当:计算机新书热卖榜第一名 京东:科技IT新书榜 ...