二叉树定义
二叉树是一种树形结构(感觉是废话),它有如下特点:
- 每个节点最多只有两棵子树,即不存在度大于2的节点(度就是树结点的直接子结点数)
- 二叉树的子树有左右之分,其次序不能任意颠倒
二叉树有什么用?
那用处可就大了,就拿我们前端熟悉的来说,抽象语法树(BST
)听过吧,babel
在编译的时候构建的BST
就是一棵二叉树,vue
里面的diff
,虚拟dom
听过吧,这些都离不开二叉树。二叉树的威力远不止如此,利用二叉树前序遍历显示目录结构
,利用二叉树中序遍历实现表达式树
,在编译器里十分有用,利用二叉树后续遍历实现计算目录内的文件以及信息
等。总而言之,二叉树对计算机领域而言可以说是无处不在,熟练运用二叉树,提升程序运行效率,提高程序可读性,优点那么多,赶紧学起来啊
二叉树遍历方式
总的来说,我们可以把遍历二叉树的方式分为4种
- 前序遍历:父结点 -> 左子树 -> 右子树
- 中序遍历:左子树 -> 父结点 -> 右子树
- 后序遍历: 左子树 -> 右子树 -> 父结点
- 层次遍历:逐层访问当前层所有结点,从上到下,从左到右
栗子,如图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gCv9hM5z-1590941522320)(http://image.jianfengke.com/tree-avscbvzc.png)]
前序遍历结果:ABDHIECFG
中序遍历结果: HDIBEAFCG
后序遍历结果: HIDEBFGCA
层次遍历: ABCDEFGHI
JS二叉树的表达
结点
function TreeNode(val) {
this.val = val;
this.left = this.right = null;
}
把上图转化为js里的树:
var tree = {
val: "A",
left: {
val: "B",
left: {
val: "D",
left: {
val: "H",
left: null,
right: null
},
right: {
val: "I",
left: null,
right: null
}
},
right: {
val: "E",
left: null,
right: null
}
},
right: {
val: "C",
left: {
val: "F",
left: null,
right: null
},
right: {
val: "G",
left: null,
right: null
}
}
}
遍历算法
一般来说,树的遍历的方法有递归遍历跟非递归遍历之分,递归遍历优点是代码简单,易于理解,但缺点是执行效率不高。而非递归遍历恰恰是相反,效率高,但代码量大,不易理解。下面先介绍前中后三种的递归遍历方法,其实也可以当作模板去用,很多关于二叉树的问题的本质还是在于遍历上。
递归遍历
前序遍历(递归):
function preOrder(root) {
if(root) {
console.log(root.value) //这里是操作的核心,可以利用该结点值进行很多操作
preOrder(root.left)
preOrder(root.right)
}
}
中序遍历(递归):
function inOrder(root) {
if(root) {
inOrder(root.left)