树
树形结构是一种非线性数据结构。
树中的每个部分称为结点,结点间存在分支结构与层次关系。
每个树型结构都有一个根节点。
根据结点之间的关系,也存在父节点、子节点、兄弟结点的概念。
不含子节点的结点称为叶结点。
子树:对某个结点与其后代结点的整体称呼。
由于存在父子关系,树中的结点形成多级结构,称为层级。
根节点层级为1,向下依次递增。
树中最深结点的层级称为树的高度。
二叉树
二叉树是树形结构中的一种,二叉树中的每个结点最多只能存在2个子节点。
左子节点、右子节点、左子树、右子树
满二叉树
二叉树的每层节点都达到最大值,称为满二叉树。
完全二叉树
二叉树的除最后一层外,每层结点都达到最大值,且最后一层结点都位于左侧,这种形式称为完全二叉树。满二叉树也属于完全二叉树。
前序遍历
/* var preorderTraversal = function(root) {
// 用于存储遍历的结果
const res = []
// 设置函数用于进行递归遍历
const preorder = (root) => {
// 当前结点为空时,无需进行递归
if (!root) {
return
}
// 记录根节点值
res.push(root.val)
// 前序遍历左子树
preorder(root.left)
// 前序遍历右子树
preorder(root.right)
}
preorder(root)
return res
}; */
const preorderTraversal = function(root) {
const res = []
const stk = []
while (root || stk.length) {
while (root) {
// 右子结点入栈
stk.push(root.right)
// 记录根节点
res.push(root.val)
// 下一步处理左子节点
root = root.left
}
// 左子树处理完毕,将 stk 出栈,处理右子树
root = stk.pop()
}
return res
}
二叉树的最大深度
前序遍历操作时使用的算法称为深度优先搜索算法(dfs)
/**
* @param {TreeNode} root
* @return {number}
*/
var maxDepth = function(root) {
if (!root) {
return 0
}
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1
};
二叉树的层序遍历
广度优先搜索算法bfs,借助于队列
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
const res = []
if (!root) {
return res
}
// 声明队列用于存储后续数据
const q = []
q.push(root)
// 遍历队列
while (q.length !== 0) {
// 针对本轮操作,创建一个新的二维数组
res.push([])
let len = q.length
for (let i = 0; i < len; i++) {
// 将本次操作的结点出队
const node = q.shift()
res[res.length - 1].push(node.val)
// 检测是否存在左右子结点,如果有,入队即可
if (node.left) {
q.push(node.left)
}
if (node.right) {
q.push(node.right)
}
}
}
return res
};
二叉搜索树
二叉搜索树是一种特殊的二叉树,简称BST。
左子树的结点小于根节点,右子树的结点大于根节点。
子树也为二叉搜索树。
// 二叉搜索树
/* var isValidBST = function(root) {
// 通过一个辅助函数来统一设置左右子树的比较
return helper(root, -Infinity, Infinity);
};
const helper = (root, lower, upper) => {
if (root === null) {
return true
}
// 当前节点值超出边界,说明二叉树为非 BST
if (root.val <= lower || root.val >= upper) {
return false;
}
// 否则,递归处理左右子节点,并更新大小范围
// 同时根据左右子节点的返回值进行返回,只有全部递归结果均为 true, 才说明二叉树为 BST
return helper(root.left, lower, root.val) && helper(root.right, root.val, upper);
} */
//第二种
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isValidBST = function(root) {
let stk = []
// 用于记录上一次取得的节点值,BST 中这个值应小于当前节点
// 设置默认值为 -Infinity 避免对比较结果产生干扰
let oldNode = -Infinity
while (root || stk.length) {
while (root) {
stk.push(root)
root = root.left
}
root = stk.pop()
// 如果任意节点比上个节点值小,说明二叉树不是 BST
if (root.val <= oldNode) {
return false
}
// 通过比较,记录当前节点值
oldNode = root.val
root = root.right
}
return true
};