二叉树
一、二叉树的理论知识
树是一种非线性结构,树只有一个根结点,其子树本身也是一棵树,所以其定义是递归定义。刷题时主要考察二叉树。
几种特殊的二叉树:满二叉树、完全二叉树、平衡树、二叉搜索树
满二叉树:叶子节点都在同一层上,深度为k,则有2^k-1个节点
完全二叉树:按层给节点编号,节点的编号是连续的。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。
平衡树:所以子树的左子树和右子树的深度差不大于2
二叉搜索树:左子树的所有节点均小于当前节点的值,右子树的所有节点均大于当前节点的值。它的左右子树也是二叉搜索树。
二、二叉树的遍历
二叉树的遍历有递归法(前中后序)、迭代法(用栈模拟递归)、层序法(借助队列实现)
(1)递归法
步骤:①明确函数的定义,确定递归的参数和返回值,如果有用来记录本层信息且会叠加的值需要作为参数(如depth或path),如果需要计算树的属性或找到一个就返回时需要有返回值(如height、true)
②确定终止条件(一般是root==null 或root为叶子节点)
③确定本层逻辑(需要考虑遍历顺序,后序遍历需要先收集左右孩子的信息)
----计算深度(根到节点-从上往下叠加)用先序,计算高度(节点到叶子节点-从下往上叠加)用后序----
(2)迭代法
思路:将访问的节点放入栈中,把要处理的节点也放入栈中但是要做标记(追加null节点)。
const stack = [];
if (root) stack.push(root);
while(stack.length) {
const node = stack.pop();
if(!node) {
res.push(stack.pop().val);
continue;
}
if (node.right) stack.push(node.right); // 右
if (node.left) stack.push(node.left); // 左
stack.push(node); // 中
stack.push(null);
};
(3)层序法
queue.push(root); while(queue.length && root!==null) { // 计算当前层级节点数量 let length = queue.length; while(length--) { let node = queue.shift(); //做某些操作 // 把下一层级的左右节点存入queue队列 node.left && queue.push(node.left); node.right && queue.push(node.right); }
二、重点
1、二叉树的性质:
1)二叉树的第i层至多有2^(i-1)个结点;
2)深度为k的二叉树至多含有2^k-1个结点;
3)n0(度为0的结点)=n2(度为2的结点)+1;
//通过总结点数的奇偶可确定是否含有度为1的结点
4)具有n个结点的完全二叉树的深度为|_log2 n_|+1;
5)对完全二叉树,若从上至下、从左至右进行编号,则编号为i的结点,其左孩子编号必为2i,右孩子编号必为2i+1,双亲为i/2。