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);
}
- 根据代码框架,来进行增删改查。