二叉搜索树 笔记
(完善中)
代码完全体
public class MyBinarySearchTree {
public static void main(String[] args) {
MyBinarySearchTree bst=new MyBinarySearchTree();
bst.insert(5);
bst.insert(3);
bst.insert(7);
bst.insert(2);
bst.insert(4);
bst.insert(6);
bst.insert(9);
bst.insert(8);
bst.insert(10);
bst.delete(7);
bst.preorderTraversal();
}
TreeNode root;
public void insert(int val){
if(root==null){
root=new TreeNode(val);
return ;
}
TreeNode cur=root;
while(true){
if(val>cur.val){
if(cur.right==null){
cur.right=new TreeNode(val);
return ;
}else{
cur=cur.right;
}
}else{
if(cur.left==null){
cur.left=new TreeNode(val);
return ;
}else{
cur=cur.left;
}
}
}
}
public TreeNode search(int val){
if(root==null)return null;
TreeNode cur=root;
while(cur!=null){
if(val==cur.val){
return cur;
}
if(val>cur.val){
cur=cur.right;
}else{
cur=cur.left;
}
}
return null;
}
public void preorderTraversal(){
if(root==null)return ;
preorder(root);
System.out.println();
}
private void preorder(TreeNode root){
if(root==null)return ;
System.out.print(root.val+"->");
preorder(root.left);
preorder(root.right);
}
public void delete(int val){
if(root==null)return ;
TreeNode parent=searchParent(val);
TreeNode target;
if(parent==null){
return ;
}
if(parent.left.val==val){
//左孩子
target=parent.left;
if(target.left==null&&target.right==null){
parent.left=null;
}else{
if(target.left!=null&&target.right!=null){
target.val=deleMinLeaf(target.right);
}else if(target.left==null){
//右子树
parent.left=target.right;
}else{
//左子树
parent.left=target.left;
}
}
}else{
//右孩子
target=parent.right;
if(target.left==null&&target.right==null){
parent.right=null;
}else{
if(target.left!=null&&target.right!=null){
target.val=deleMinLeaf(target.right);
}else if(target.left==null){
//右子树
parent.right=target.right;
}else{
//左子树
parent.right=target.left;
}
}
}
}
public TreeNode searchParent(int val){
if(root==null)return null;
if(val==root.val){
TreeNode cur=new TreeNode(val+1);
cur.left=root;
return cur;
}
TreeNode cur=root;
while(cur!=null){
if((cur.left!=null&&cur.left.val==val)||(cur.right!=null&&cur.right.val==val)){
return cur;
}else{
if(val>cur.val){
cur=cur.right;
}else{
cur=cur.left;
}
}
}
return null;
}
public int deleMinLeaf(TreeNode root){
TreeNode cur=root;
while (cur!=null&&cur.left!=null)cur=cur.left;
delete(cur.val);
return cur.val;
}
}
class TreeNode{
int val;
TreeNode left;
TreeNode right;
TreeNode(int val){
this.val=val;
}
}
编写思路
要点
- 在二叉搜索树中
left.val<cur.val
right.val>cur.val
insert
举例
假如我们要插入的节点分别为:5、2、3
首先,root.val 会变为 5
然后,root.left.val 会变成 2
最后,最左边的叶子节点变为3
(可以对着代码自己手画一遍)
search
如果val
比cur.val
大,那我们就会去cur的右孩子找,反之向左孩子去找
traversal
和普通的二叉树遍历方法一样
删除
重中之重
-
判断要删除节点属于哪种类型
- 叶子节点
- 有一颗子树的节点
- 有两颗子树的节点
- 根节点