基础知识

二叉树基础知识

二叉树多考察完全二叉树、满二叉树,可以分为链式存储和数组存储,父子兄弟访问方式也有所不同,遍历也分为了前中后序遍历层次遍历

Java定义

public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}

递归遍历

这个简单就不赘述了

迭代遍历

考研期间跟着王道走过一遍迭代遍历,建议画个简单的数模拟一下,自然写出代码,画图模拟

/**
* 前序 深度相关
*/
public List<Integer> preOrder(TreeNode root) {
TreeNode p = root;
ArrayDeque<TreeNode> stack = new ArrayDeque<>();
// 存放结果 visit操作
List<Integer> result = new ArrayList<>();
// p不空,或者栈不空,表示要进行入栈或出栈操作,两个都空表示结束
while (p != null || !stack.isEmpty()) {
if (p != null) {
// visit p
result.add(p.val);
stack.push(p);
p = p.left;
} else {
p = stack.pop();
p = p.right;
}
}
return result;
}
/**
* 中序 顺序相关
*/
public List<Integer> inOrder(TreeNode root) {
TreeNode p = root;
ArrayDeque<TreeNode> stack = new ArrayDeque<>();
// 存放结果 visit操作
List<Integer> result = new ArrayList<>();
// p不空,或者栈不空,表示要进行入栈或出栈操作,两个都空表示结束
while (p != null || !stack.isEmpty()) {
if (p != null) {
stack.push(p);
p = p.left;
} else {
p = stack.pop();
// visit p
result.add(p.val);
p = p.right;
}
}
return result;
}
/**
* 后序遍历 高度相关
*/
public List<Integer> postOrder(TreeNode root) {
TreeNode p = root;
// 每个点都可能有一个右孩子,在访问根节点之前要保证访问过它的右孩子
TreeNode r = null;
ArrayDeque<TreeNode> stack = new ArrayDeque<>();
// 存放结果 visit操作
List<Integer> result = new ArrayList<>();
while (p != null || !stack.isEmpty()) {
if (p != null) {
stack.push(p);
// 走到树的最左边
p = p.left;
} else {
// 读栈顶指针,这里是乐观思路
p = stack.peek();
// 若右子树存在且未被访问
if (p.right != null && p.right != r) {
p = p.right;
} else {
p = stack.pop();
// visit
result.add(p.val);
// 更新被访问点
r = p;
// 重置p指针,从栈中获取
p = null;
}
}
}
return result;
}

总结

递归三要素

  1. 确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。

  2. 确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。

  3. 确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

常用变量名增量更新

size、val、ans、cnt、cur、pre、next、left、right、index、gap、tar、res、src、len、start、end、flag、ch

最新文章

  1. 编译器开发系列--Ocelot语言5.表达式的有效性检查
  2. Fiddler2 主菜单
  3. FreeRTOS和Ucos在打开关闭中断的区别
  4. FlowVisor 安装
  5. 三种主流的WebService实现方案(REST/SOAP/XML-RPC)简述及比较
  6. QCustomPlot使用手冊(三)
  7. ASP.NET 导入excel 数据
  8. 简述public private protected internal修饰符的访问权限
  9. 关于ZendStudio 10.5的破解
  10. python 小白(无编程基础,无计算机基础)的开发之路 辅助知识1 with...as
  11. 【转载】SSD 下的 MySQL IO 优化
  12. golang 安装tensorflow
  13. 始于阿里,回归社区:阿里8个项目进入CNCF云原生全景图
  14. Iar8.1安装包破解
  15. day19 正则,re模块
  16. Django中media的配置
  17. Linux进程间通信(System V) --- 共享内存
  18. QT数据类型
  19. [MySQL]典型的行列转换
  20. Window下部署Maven Nexus

热门文章

  1. Kettle基础及快速入门
  2. v-model双向绑定原理
  3. Nginx rewrite 详解
  4. 安装es可视化软件Kibana
  5. 直播报名|资深云原生架构师分享服务网格在腾讯 IT 业务的落地实践
  6. CVE-2020-1938与CVE-2020-13935漏洞复现
  7. JavaScript:操作符:逻辑运算符及其隐式转换数据类型
  8. [MySQL] 索引的使用、SQL语句优化策略
  9. kafka详解(04) - kafka监控 可视化工具
  10. JS加载层