feat: 添加二叉搜索树98,230,530,1382

This commit is contained in:
LouisFonda 2025-06-07 16:15:46 +08:00
parent f53e76dcf0
commit 21d1a55888
Signed by: yigencong
GPG Key ID: 29CE877CED00E966
4 changed files with 239 additions and 0 deletions

View File

@ -0,0 +1,65 @@
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val === undefined ? 0 : val);
* this.left = (left === undefined ? null : left);
* this.right = (right === undefined ? null : right);
* }
*/
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
const balanceBST = function (root) {
};
/*
现在不来考虑二叉搜索树变平衡考虑一下给你一个有序的数组你如何将他变平衡我的猜想是这样的直接寻找找到数组序列的中间位置mid =Math.floor(left + right)
将mid作为这个根节点将mid左侧的元素(不是小于等于)全部用来构建左子树将mid右侧的元素全部用来构建右子树之后在子树上重复这个过程最后构建出来的树
就是一棵平衡二叉搜索树原因很简单log2(k),和log2(k+1)的差不会超过1一个区间被分割无外乎两种情况左边和右边的数量相等或者左边和右边的数量相差
1这是满足平衡二叉树定义的所以这种构建的贪心策略是合理的
记住一个有序的序列只要取中间值作为根节点左右侧序列作为左右子树之后递归处理左右子树最终就能构建一颗平衡二叉搜索树而二叉搜索树的中序遍历恰好
是有序序列所以只需要将二叉搜索树遍历之后拿到遍历的结果重新按照上面的方法构建一颗平衡二叉搜索(BST)树就行
*/
function TreeNode(val, left, right) {
this.val = (val === undefined ? 0 : val);
this.left = (left === undefined ? null : left);
this.right = (right === undefined ? null : right);
}
function f1(root) {
// 1.遍历二叉搜索树(BST)获取对应有序序列
const inorder = [];
const inorderTraversal = (root) => {
if (!root) return;
// 遍历左子树
inorderTraversal(root.left);
// 将中序遍历的值存入数组
inorder.push(root.val);
// 遍历右子树
inorderTraversal(root.right);
};
inorderTraversal(root); // 对原始树进行中序遍历
// 2.递归构建平衡二叉搜索树
const sortedArrayToBST = (left, right) => {
if (left > right) return null; // 当前区间不存在元素,无法构建子树
const mid = Math.floor((left + right) / 2);
// 为当前区间所有元素构建根节点
const curRoot = new TreeNode(inorder[mid]);
// 递归构建左子树
const leftNode = sortedArrayToBST(left, mid - 1);
// 递归构建右子树
const rightNode = sortedArrayToBST(mid + 1, right);
// 连接左右子树
curRoot.left = leftNode;
curRoot.right = rightNode;
return curRoot;
};
return sortedArrayToBST(0, inorder.length - 1);
}

View File

@ -0,0 +1,52 @@
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} k
* @return {number}
*/
const kthSmallest = function (root, k) {
};
/*
根据二叉搜索树的特性直接对其进行中序遍历遍历到的第k个数就是第k小这里使用迭代的方式好返回结果
*/
function f1(root, k) {
const stack = []; // 栈用于模拟中序遍历
let node = root; // 从根节点开始遍历
while (node || stack.length > 0) {
// 先处理左子树,将所有左子树节点压入栈中
while (node) {
stack.push(node);
node = node.left;
}
// 弹出栈顶元素并访问
node = stack.pop();
// 递减k如果k为0说明我们已经找到了第k个最小值
if (--k === 0) {
return node.val;
}
// 处理右子树
node = node.right;
}
return null; // 如果没有找到k个元素返回null一般不会发生
}
/*
当一如果当前节点就是目标节点那么它的左子树的数量一定是k-1如果左子树的数量小于k-1个那么目标节点一定存在右子树中
以当前节点右子树为根节点继续寻找此时k要出去左子树的left加上自己一共left + 1所以以右子节点为更节点的子树只需寻找
k-(left+1)个大的数使用面向对象的写法封装
*/
// TODO

View File

@ -0,0 +1,52 @@
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
const getMinimumDifference = function (root) {
};
/*
二叉搜索树的一个重要特征就是中序遍历的结果是一个升序序列所以只要中序遍历整个二叉树前一个节点和当前节点作比较的值的绝对值就可能
是这个最小的差值
*/
function f1(root) {
let prev = null; // 记录前一个节点的值
let minDiff = Infinity; // 初始化最小差值为正无穷
// 中序遍历函数
function inOrder(node) {
if (!node) return;
// 先遍历左子树
inOrder(node.left);
// 当前节点与前一个节点的差值
if (prev !== null) {
minDiff = Math.min(minDiff, Math.abs(node.val - prev));
}
// 更新前一个节点为当前节点
prev = node.val;
// 再遍历右子树
inOrder(node.right);
}
// 从根节点开始中序遍历
inOrder(root);
return minDiff;
}
/*
使用迭代实现中序遍历
*/

View File

@ -0,0 +1,70 @@
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
const isValidBST = function (root) {
};
/*
思路根据二叉搜索树的定义BST的中序遍历是一个严格的递增序列所以只要一次遍历判断后一个树是否是严格大于当前的树如果小于等于
那么这个二叉树不是搜索二叉树
*/
function f1(root) {
let prev = null; // 前一个节点的值
const inordertraversal = (node) => {
if (!node) return true; // 空节点被视为有效BST
// 遍历左子树如果左子树不是BST立即返回false
if (!inordertraversal(node.left)) return false;
// 处理当前节点
if (prev !== null && prev >= node.val) return false;
// 更新prev为当前节点值
prev = node.val;
// 遍历右子树
return inordertraversal(node.right);
};
return inordertraversal(root);
}
/*
使用迭代法中序遍历返回更直接
*/
function f2(root) {
const stack = [];
let prev = null;
// 迭代法中序遍历
while (stack.length > 0 || root !== null) {
// 遍历左子树,直到最左叶子节点
while (root !== null) {
stack.push(root);
root = root.left;
}
// 访问当前节点
root = stack.pop();
// 当前节点值必须大于前一个节点值
if (prev !== null && root.val <= prev) {
return false; // 发现不符合要求返回false
}
// 更新prev为当前节点值
prev = root.val;
// 访问右子树
root = root.right;
}
return true;
}