判断BST的合法

最容易想到的就是套用我们的先序遍历框架

boolean isValidBST(TreeNode root){
if(root==null){
return true;
}
if(root.left!=null&&root.val<=root.left.val){
return false;
}
if(root.right!=null&&root.val>=root.right.val){
return false;
}
return isValidBST(root.left)&&isValidBST(root.right);
}

增加参数列表,在参数中携带额外信息,通过辅助函数将上层节点的约束传递下来

boolean isValidBST(TreeNode root,TreeNode min,TreeNode max){
if(root==null){
return true;
}

boolean isValidBST(TreeNode root,TreeNode min,TreeNdoe max){
//base case
if(root==null){
return true;
}
//若root.val不符合max和min的限制,说明不是合法BST
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);
}

在BST中搜索一个数

这个比较简单,直接放框架代码

void BST(TreeNode root,int target){
if(root.val==target){
//找到目标,做点什么
}
if(root.val<target){
BST(root.right,target);
}
if(root.val>target){
BST(root.left,target);
}
}

在BST中插入一个数

一旦涉及[改],函数就要返回TreeNode类型,并且对递归调用的返回值进行接收

TreeNode insertIntoBST(TreeNode root,int val){
//找到空位置插入新节点
if(root==null){
return new TreeNode(val);
}
//if(root.val==val)
//BST中一般不会插入已存在的元素
if(root.val<val){
root.right=insertIntoBST(root.right,val);
}
if(root.val>val){
root.left=insertIntoBST(root.left,val);
}
return root;
}

在BST中删除一个数(重点)

TreeNode deleteNode(TreeNdde 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=deleNode(root.right,key);
}
return root;
}

思考删除节点时我们需要干什么?
情况1:A恰好是末端节点,两个节点都为空,那么它可以当场去世了
选区_186.png

if(root.left==null&&root.right==null){
return null;
}

情况2:A只有一个非空子节点,那么它要让这个孩子接替自己的位置
选区_187.png
if(root.left==null) return root.right;
if(root.right==null) return root.left;
情况3:A有两个子节点,为了不破坏BST的性质,A必须找到左子树中最大的那个节点,或者右子树中最小的那个节点来接替自己。

if(root.left!=null&&root.right!=null){
//找到右子树的最小节点
TreeNode minNode=getMin(root.right);
//把root改成minNode
root.val=minNode.val;
//删除minNode
root.right=deleteNode(root.rigth,minNode.val);
}

框架代码

TreeNode deleteNode(TreeNode root,int key){
if(root==null){
return null;
}
if(root==key){
//这两个if把情况1和2都正确地处理了
if(root.left==null) return right;
if(root.right==null) return left;
//处理情况3
TreeNode minNode=getMin(root.right,minNode.val);
root.val=minNdode.val;
root.right=deleteNode(root.right,minNode.val);
}else if(root.val>key){
root.let=deleteNode(root.left,key);
}else if(root.val<key){
root.right=deleteNode(root.right,key);
}
return root;
}

TreeNdoe getMin(TreeNode node){
//BST最左边的就是最小的
while(node.left!=null){
node=node.left;
}
}

最后总结
1.如果当前节点会对下面的子节点有整体影响,可以通过辅助函数增长参数列表
2.BST框架代码

void BST(TreeNode root, int target) {
    if (root.val == target)
        // 找到目标,做点什么
    if (root.val < target) 
        BST(root.right, target);
    if (root.val > target)
        BST(root.left, target);
}

ChangZhu
8 声望1 粉丝

但将行好事,莫要问前程