二叉树
1.平衡二叉树:任意一个节点其左节点的层数与右节点的层数相差不超过一
2.完全二叉树:除了叶子节点 之外每个节点都有两个子节点
3.满二叉树:
(1) 所有层都是满的
(2) 要么没有子节点,有子节点就必须要有两个
eg:平衡二叉树
eg:完全二叉树
eg:满二叉树
二叉树的描述方式
1.前序:首先访问根节点 ( 根-> 左 -> 右)
2.中序: 中间访问根节点( 左-> 根 -> 右)
3.后序: 最后访问根节点 ( 左-> 右 -> 根)
代码构造二叉树
1.菜鸟写法
1 | function Node(data, left, right) { |
这样写确实通俗易懂,但是实现起来所占空间实在是不敢恭维,所以我们是不是有什么办法,用更少的空间存储二叉树呢
2.进阶写法
1 | function pre(node) { //传入一棵树 |
根据前序/中序遍历、后序/中序遍历确定一棵二叉树
为了方便,我们先把三种遍历方式的顺序写出来1
2
3var pre = [1,2,4,5,3,6]; //前序
var mid = [4,2,5,1,3,6]; //中序
var aft = [4,5,2,6,3,1]; //后序
1.前序/中序遍历1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29function perMid(pre, mid) {
if(pre.length == 0 || mid.length == 0) {
return null;
}
if (pre.length != mid.length) {
throw Error('参数不正确')
}
// 根节点数据
var rootData = pre[0];
// 根节点在中序遍历中的位置
var midRootIndex = mid.indexOf(rootData);
// 左子树中序遍历
var leftMid = mid.slice(0, midRootIndex); //截取中序数组根节点之前的为左子树
// 右子树中序遍历
var rightMid = mid.slice(midRootIndex + 1); //截取中序数组根节点之后的为右子树
// 左子树前序遍历
var leftPre = pre.slice(1, leftMid.length + 1); /*截取前序数组:第一项是根节点所以从第二项开始截取,截取长度为左子树节点个数
所以截取到leftMid.length + 1的位置(slice不含下标为leftMid.length + 1)*/
// 右子树前序遍历
var rightPre = pre.slice(leftMid.length + 1); //从leftMid.length + 1的位置开始截取,到最后
// 左子树还原
var left = perMid(leftPre, leftMid); //递归,传入左子树的前、中序遍历
// 右子树还原
var right = perMid(rightPre, rightMid); //同上
// 最终二叉树
var node = new Node(pre[0], left, right);
return node;
}
2.后序/中序遍历1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28function afterMid(aft, mid) {
if(aft.length == 0 || mid.length == 0) {
return null;
}
if (aft.length != mid.length) {
throw Error('参数不正确')
}
// 根节点数据
var rootData = aft[aft.length - 1];
// 根节点在中序遍历中的位置
var midRootIndex = mid.indexOf(rootData);
// 左子树中序遍历
var leftMid = mid.slice(0, midRootIndex);
// 右子树中序遍历
var rightMid = mid.slice(midRootIndex + 1);
// 左子树后序遍历
var leftAft = aft.slice(0, leftMid.length);
// 右子树后序遍历
var rightaft = aft.slice(leftMid.length, aft.length - 1);
// 左子树还原
var left = afterMid(leftAft, leftMid);
// 右子树还原
var right = afterMid(rightaft, rightMid);
// 最终二叉树
var node = new Node(aft[aft.length - 1], left, right);
return node;
}