(算法)二叉搜索树

77 阅读2分钟

查找数据域为某一特定值的结点

题解:

/** 
* @param {TreeNode} root
* @param {number} n
* @return {TreeNode}
*/
const search = (root, n) => {
    if(!root) return;
    
    if(root.val === n) return root;
    if(root.val > n) {
      search(root.left);
    }else {
      search(root.right);
    }
    return null;
}

规则:

二叉搜索树强调的是数据域的有序性,满足 左孩子 < 根结点 < 右孩子 的大小关系

插入新结点

/** 
* @param {TreeNode} root
* @return {number[]}
*/
const insertIntoBST = (root, n) => {
    if(!root){
      root = new TreeNode();
      return root;
    }
    
    if(root.val > n){
      root.left = insertIntoBST(root.left, n);
    }else {
      root.right = insertIntoBST(root.right, n);
    }
    return root;
  }

规则:

二叉搜索树的查找路线是一个非常明确的

删除指定节点

/** 
* @param {TreeNode} root
* @return {number[]}
*/
const deleteNode = (root, n) => {
    if(!root){
      return root;
    }
    
    if(root.val === n){
        // 无子节点时置为null即可
        if(!root.left && !root.right){
            root = null
        }else if(root.left){
            // 寻找左子树里值最大的结点
            const maxLeft = findMax(root.left);
            // 改掉当前节点值
            root.val = maxLeft.val;
            //删除左树最大值并覆盖原有左树
            root.left = deleteNode(root.left, maxLeft.val);
        }else{
            // 寻找右子树里值最大的结点
            const minRight = findMin(root.right)
            // 改掉当前节点值
            root.val = minRight.val;
            //删除右树最大值并覆盖原有右树
            root.right = deleteNode(root.right, minRight.val);
        }
    } else if(root.val > n){
      root.left = deleteNode(root.left, n);
    } else {
      root.right = deleteNode(root.right, n);
    }
    return root;
  }
  
  // 查找最大值
  function findMax(root){
      while(root.right){
          root = root.right;
      }
      
      return root;
  }
  
  // 查找最小值
  function findMin(root){
      whilt(root.left){
          root = root.left;
      }
      
      return root;
  }

规则:

二叉搜索树的中序遍历序列是有序的

二叉搜索树的验证

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

示例:

输入:
    2
   / \
  1   3
输出: true

输入: 
    5
   / \
  1   4
     / \
    3   6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。  
根节点的值为5,但是其右子节点值为4

题解:

/** 
* @param {TreeNode} root
* @return {boolean}
*/
const isValidBST = (root) => {
    // 递归
    const dfs = (r, min, max) => {
        if(!root){
            return true;
        }
        
        // 此时不为搜索二叉树
        if(root.val <= min || root.val >= max) return false;
        
        // 尾递归, 左右子树都需符合数据域大小关系
        return dfs(root.left, min, root.val) && dfs(root.right, root.val, max);
    }
    
    // 初始化最小值和最大值
    return dfs(root, -Infinity, Infinity)
}

规则:

检验每棵子树中是否都满足 左 < 根 < 右 的关系

将排序数组转化为二叉搜索树

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。 高度平衡二叉树是指二叉树每个节点的左右两个子树的高度差的绝对值不超过 1

示例:

给定有序数组: [-10,-3,0,5,9],
一个可能的答案是: [0,-3,9,-10,null,5]
它可以表示下面这个高度平衡二叉搜索树: 
      0
     / \
   -3   9
   /   /
 -10  5

题解:

/** 
* @param {number[]} nums
* @return {TreeNode}
*/
const sortedArrayToBST = (root) => {
    // 边界
   if(!nums.length){
       return null
   }
   
   // 构造根节点
   const root = buildBST(0,nums.length - 1);
   // 参数为序列的索引范围
   function buildBST(low,high){
       if(low > high){
           return null;
       }
       // 取中间元素
       const mid = Math.floor(low + (high - low)/2);
       // 构造中间节点
       const cur = new TreeNode(nums[min]);
       // 递归构建左子树
       cur.left = buildBST(low, min - 1);
       // 递归构建右子树
       cur.right = buildBST(mid + 1, high);
       
       retrun cur;
   }
   
   retrun root;
}

规则:

给出的数组就是目标二叉树的中序遍历序列, 左 -> 根 -> 右