这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
树
树的结构十分直观,而树的很多概念定义都有一个相同的特点:递归,也就是说,一棵树要满足某种性质,往往要求每个节点都必须满足。例如,在定义一棵二叉搜索树时,每个节点也都必须是一棵二叉搜索树。
正因为树有这样的性质,大部分关于树的面试题都与递归有关。
树的形状
在面试中常考的树的形状有:普通二叉树、平衡二叉树、完全二叉树、二叉搜索树、四叉树(Quadtree)、多叉树(N-ary Tree)。
对于一些特殊的树,例如红黑树(Red-Black Tree)、自平衡二叉搜索树(AVL Tree),一般在面试中不会被问到,除非你所涉及的研究领域跟它们相关或者你十分感兴趣,否则不需要特别着重准备。
关于树的考题,无非就是要考查树的遍历以及序列化(serialization)。
题目1:树的层次遍历
解题思路
层次遍历是对树的每一层的结点进行遍历。层次遍历是广度优先遍历
代码实现
function treeNode(val) {
this.val = val; // 当前结点的值
this.left = null; //指向左子节点
this.right = null; //指向右子节点
}
var treeSearch = function(root) {
if(!root) return [];
let res = [];
let q = [root];
while(q.length > 0){
let tmp = [];
let temp = [];
for(let i in q){
let p = q[i];
temp.push(p.val);
p.left && tmp.push(p.left);
p.right && tmp.push(p.right);
}
q = tmp;
res.push(temp);
}
return res;
};
题目2 : 判断二叉树 A 中是否包含子树 B
解题思路
查找A树中是否存在B树的结构一样的子树,需要B树中的结点都存在于A树中。需要使用2个递归
第一步:在A树中找到和B树的根结点一样的结点值C,如果没有说明不存在。此过程可以使用递归的方法遍历或者循环的方法遍历
第二步:判断A树中以结点C为结点的子结点是否和B树子节点一样,如果存在不一样,继续寻找看是否存在其他结点和B树的根结点一样。
代码实现
function isExistTree(node, tNode) {
if (!tNode) return true;
if (!node) return false;
if (node.val === tNode.val && findNode(node.left, tNode.left)&& findNode(node.right, tNode.right)) {
return true
} else {
isExistTree(node.left,tNode) || isExistTree(node.right,tNode)
}
}
function findNode(A, B) {
if (!A) return false
if (!B) return true
if (A.val !== B.val) {
return false
}
return find(A.left, B.left) && find(A.right, B.right)
}