数据结构,就是强调用合适的结构来对数据进行遍历或者说增删改查 对于算法就是通过其对结果进行穷举遍历找解
所有数据结构,都是由最基本的数组,和链表得来
二叉树
先在开头总结一下,二叉树解题的思维模式分两类:
1、是否可以通过遍历一遍二叉树得到答案?如果可以,用一个 traverse 函数配合外部变量来实现,这叫「遍历」的思维模式。
2、是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案?如果可以,写出这个递归函数的定义,并充分利用这个函数的返回值,这叫「分解问题」的思维模式。
无论使用哪种思维模式,你都需要思考:
如果单独抽出一个二叉树节点,它需要做什么事情?需要在什么时候(前/中/后序位置)
二叉树, 如果是遍历一遍得到答案是回溯思想 如果需要分解,那是动态规划思想
二叉树
定义
概念
- 子节点,父节点,叶子节点
分类
- 满二叉树 : 特点每个节点都是两个,总节点数量等于 2^h - 1
- 完全二叉树
- 二叉搜索树: 对于每一个节点,左子树的每个节点值,都小于它,右子树每个节点都大于它(注意是每个意味着对于根节点的左子树的每个点都小于右子树每个节点)
二叉树实现
通过链表方式来解决
var TreeNode = function(x) {
this.val = x;
this.left = null;
this.right = null;
}
// 你可以这样构建一棵二叉树:
var root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.right.left = new TreeNode(5);
root.right.right = new TreeNode(6);
// 构建出来的二叉树是这样的:
// 1
// / \
// 2 3
// / / \
// 4 5 6
二叉树遍历方式-dfs
class TreeNode {
constructor(val) {
this.val = val;
this.left = null;
this.right = null;
}
}
// 二叉树的遍历框架
var traverse = function(root) {
if (root === null) {
return;
}
traverse(root.left);
traverse(root.right);
}
注意
- 不论是哪种遍历方式,始终都是一致的,先递归左子树,再去递归右子树,所谓的前,中后遍历取决于你怎么去处理
深入理解二叉树的前中后序遍历是什么
- 仅仅是三个顺序不同的 List 吗?
2、请分析,后序遍历有什么特殊之处?
3、请分析,为什么多叉树没有中序遍历?前中后序遍历
前序遍历位置,处于即将遍历一个节点的时机 后序遍历处于,刚离开一个节点 中序处于 左子树遍历完毕,即将遍历右子树