108.将有序数组转成二叉搜索树
function TreeNode(val, left, right) {
this.val = (val === undefined ? 0 : val)
this.left = (left === undefined ? null : left)
this.right = (right === undefined ? null : right)
}
/**
* @param {number[]} nums
* @return {TreeNode}
*/
// 此解法只能得到二叉搜索树,不能得到高度平衡二叉树。应使用递归找中间点为根节点不断分割左右子树
var sortedArrayToBST = function (nums) {
// 先找到nums的中点,将nums分为左右子树,中点即为根节点
const mid = Math.floor(nums.length / 2)
const root = new TreeNode(nums[mid])
// 遍历nums往root插入节点
// 注意:这种插入解法符合二叉搜素树,但是不符合高度平衡二叉树
// 高度平衡二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
// 举例:输入[0,1,2,3,4,5],这种解法的结果[3,0,4,null,1,null,5,null,2],左子树有两棵子树高度差大于1了。
for (let i = 0; i < nums.length; i++) {
if (i !== mid) {
// 插入节点,bst二叉树:左节点<父节点<右节点
let newNode = new TreeNode(nums[i])
let cur = root
while (true) {
if (newNode.val < cur.val) {
if (cur.left === null) {
cur.left = newNode
break
}
cur = cur.left
} else {
if (cur.right === null) {
cur.right = newNode
break
}
cur = cur.right
}
}
}
}
return root
};
/**
* 层序遍历
* @param {TreeNode} root
*/
function levelOrder(root) {
let queue = [] // 每一层的节点
queue.push(root) // 第一层
let res = []
while (queue.length > 0) {
let len = queue.length // 当前层节点数
// 遍历每一层,取出节点
for (let i = 0; i < len; i++) {
let node = queue.shift() // node有可能为null
res.push(node ? node.val : null)
// 添加下一层的节点到队列
if (node) {
queue.push(node.left)
queue.push(node.right)
}
}
}
return res
}
/**
* @param {number[]} nums
* @return {TreeNode}
*/
var sortedArrayToBST = function (nums) {
// 先找到nums的中点,将nums分为左右子树,中点即为根节点
// 再从左子树和右子树的nums里分别找到左子树的根节点和右子树的根节点,同理中点即为根节点
// 再从分出的更小的左子树和右子树里找根节点
// ......
// 以此类推,其实是一个递归的过程
if (!nums.length) { // 递归结束条件
return null
}
const mid = Math.floor(nums.length / 2)
const root = new TreeNode(nums[mid])
let leftNums = nums.slice(0, mid) // 左子树的节点
let rightNums = nums.slice(mid + 1) // 右子树的节点
root.left = sortedArrayToBST(leftNums) // root的左节点即为左子树的根节点
root.right = sortedArrayToBST(rightNums) // root的右节点即为右子树的根节点
return root
}
// let root = sortedArrayToBST([-10, -3, 0, 5, 9])
let root = sortedArrayToBST([0, 1, 2, 3, 4, 5])
console.log(levelOrder(root))