二叉树的最大深度
递归法:
- 确定递归函数的参数和返回值:参数就是传入树的根节点,返回就返回这棵树的深度,所以返回值为int类型。
- 确定终止条件:如果为空节点的话,就返回0,表示高度为0。
- 确定单层递归的逻辑:先求它的左子树的深度,再求右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度。
代码实现
//后序递归 精简版
var maxDepth = function (root) {
if (root === null) {
return 0
}
return 1 + Math.max(treenode(root.left), treenode(root.right))
}
//正常版本
var maxDepth = function (root) {
if (root === null) {
return 0
}
let leftDepth = maxDepth(root.left)
let rightDepth = maxDepth(root.right)
let depth = 1 + Math.max(leftDepth, rightDepth)
return depth
}
n叉树的最大深度
代码实现:
//递归
var maxDepth = function (root) {
if (root === null) {
return 0
}
let depth = 0;
for (let node of root.children) {
depth = Math.max(depth, maxDepth(node))
}
return depth + 1
}
//层序
var maxDepth = function (root) {
if (root === null) {
return 0
}
let count = 0
const queue = [root]
while (queue.length) {
let size = queue.length
count++
while (size--) {
let node = queue.shift()
for (let item of node.children) {
item && queue.push(item)
}
}
}
return count
}
二叉树的最小深度
思路:
使用后序遍历,其实求的是根节点到叶子节点的最小距离,就是求高度的过程,不过这个最小距离 也同样是最小深度。
代码实现:
//递归 后序遍历
var minDepth = function (root) {
if (root === null) {
return 0
}
let leftDepth = minDepth(root.left)
let rightDepth = minDepth(root.right)
if (root.left === null && root.right !== null) {
return 1 + rightDepth
}
if (root.right === null && root.left !== null) {
return 1 + leftDepth
}
let depth = 1 + Math.min(leftDepth, rightDepth)
return depth
}
//精简版
var minDepth = function (root) {
if (root === null) {
return 0
}
let leftDepth = minDepth(root.left)
let rightDepth = minDepth(root.right)
if (root.left === null && root.right !== null) {
return 1 + minDepth(root.right)
}
if (root.right === null && root.left !== null) {
return 1 + minDepth(root.left)
}
return 1 + Math.min(minDepth(root.left), minDepth(root.right))
}
//前序
var minDepth = function (root) {
if (root === null) {
return 0
}
if (root.left === null && root.right === null) {
return 1
}
let leftDepth = minDepth(root.left)
let rightDepth = minDepth(root.right)
if (root.left === null && root.right !== null) {
return 1 + rightDepth
}
if (root.right === null && root.left !== null) {
return 1 + leftDepth
}
let depth = 1 + Math.min(leftDepth, rightDepth)
return depth
}
//层序遍历
var maxDepth = function (root) {
if (root === null) {
return 0
}
let count = 0
const queue = [root]
while (queue.length) {
let size = queue.length
count++
while (size--) {
let node = queue.shift()
node.left && queue.push(node.left)
node.right && queue.push(node.right)
if (node.left === null && node.right === null) {
return count
}
}
}
return count
}
222.完全二叉树的节点个数
代码实现:
//递归版本
var countNodes = function (root) {
const getNodeSum = function (root) {
if (node === null) {
return 0
}
let leftNum = countNodes(root.left)
let rightNum = countNodes(root.right)
return leftNum + rightNum + 1
}
return getNodeSum(root)
}
//层序
var countNodes = function (root) {
if (root === null) {
return 0
}
let queue = [root]
let nodeNums = 0
while (queue.length) {
let size = queue.length
while (size--) {
let node = queue.shift()
nodeNums++
node.left && queue.push(node.left)
node.right && queue.push(node.right)
}
}
return nodeNums
}
//利用完全二叉树的性质
var countNodes = function (root) {
if (root === null) return 0
let left = root.left,
right = root.right,
rightDepth = 0,
leftDepth = 0;
while (left) {
left = left.left
leftDepth++
}
while (right) {
right = right.right
rightDepth++
}
if (rightDepth == leftDepth) {
return Math.pow(2, leftDepth + 1) - 1
}
return countNodes(root.right) + countNodes(root.left) + 1
}
总结:
总体来说不算特别难理解 但是迭代和递归法 还是比较复杂,很难一次性记住 尤其是前中后序的使用场景 更需要铭记于心