【LeetCode算法学习笔记】二叉搜索树第二期

labuladong算法公众号学习笔记
判断BST的合法性、增、删、改、查。

BST的合法性

重点:BST中,root的整个左子树都要小于root.val,整个右子树都要大于root.val。
所以问题在于,怎么把root的约束传递给左右子树。

boolean isValidBST(TreeNode root){
    return isValidBST(root,null,null);
}
boolean isValidBST(TreeNode root,TreeNode min,TreeNode max){
    if(root == null) return false;
    if(min != null && root.val <= min.val) return false;
    if(max != null && root.val >= max.val) return false;
    //限定左子树最大值为root.val,右子树最小值为root.val
    return isValidBST(root.left,min,root) & isValidBST(root.right,root,max);
}

小技巧:通过使用辅助函数,增加函数参数列表,在参数中携带额外信息,将这种约束传递给每个子树的所有节点。

搜索一个数

在二叉树中寻找元素,为:

boolean isInBST(TreeNode root,int target){
    if(root == null) return false;
    if(root.val == target) return true;
    return isInBST(root.left, target) || isInBST(root.right, target);
}

利用BST[左小右大]的特性:

boolean isInBST(TreeNode root,int target){
    if(root == null) return false;
    if(root.val == target) return true;
    if(root.val < target) return isInBST(root.right,target);
    if(root.val > target) return isInBST(root.left,target);
}

针对BST的遍历框架(*)

void BST(TreeNode root,int target){
    if(root.val == target) //操作
    if(root.val < target) BST(root.right,target);
    if(roo.val > target) BST(root.left,target);
}

插入一个数

遍历 + 访问,找到插入位置,然后插入。
一旦涉及到[改],函数就要返回TreeNode类型,并且对递归调用的返回值进行接收。

boolean insertIntoBST(TreeNode root,int val){
    if(root == null) return new TreeNode(val);
    if(root.val == target) return true;
    if(root.val < val) root.right = insertIntoBST(root.right,val);
    if(root.val > val)  root.left = insertIntoBST(root.left,val);
    return root;
}

删除一个数

先写一个框架出来:

TreeNode deleteNode(TreeNode root,int key){
    if(root.val == key) //找到,进行删除
    else if(root.val < key) root.left = deleteNode(root.left,key);
    else if(root.val > key) root.right = deleteNode(root.right,key);
    return root;
}

删除节点A有三种情况:
1、A恰好是末端节点,两个子节点都为空,则可以直接删除。
2、A只有一个非空节点,则让该子节点替代自己的位置,然后删除A。
3、A有两个子节点,为了不破坏BST的性质,A必须找到左子树中最大的那个节点,或者右子树中最小的节点替代自己。
所以完整代码为:

TreeNode deleteNode(TreeNode root,int key){
    if(root == null) return null;
    if(root.val == key){
        //包含了情况1和情况2
        if(root.left == null) return root.right;
        if(root.right == null) return root.left;
        TreeNode minNode = getMin(root.right);
        root.val = minNode.val;
        root.right = deleteNode(root.right,minNode.val);
    }else if(root.val > key){
        root.left = deleteNode(root.left,key);
    }else if(root.val < key){
        root.right = deleteNode(root.right,key);
    }
    return root;
}
TreeNode getMin(TreeNode node){
    //BST最左边的就是最小值
    while(node.left != null) node = node.left;
    return node;
}

最后总结

  • 如果当前节点会对下面的子节点有整体影响,可以通过辅助函数增长参数列表,借助参数传递信息。
  • 在二叉树递归框架下,扩展出来BST代码框架:
void BST(TreeNode root,int target){
    if(root.val == target) //操作
    if(root.val < target) BST(root.right,target);
    if(roo.val > target) BST(root.left,target);
}
  • 根据代码框架,来进行增删改查。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值