12.10 二叉搜索树与内部类

目录

一.二叉搜索树

1 概念

2 操作-查找

3.插入

4.删除(难点)

1.cur.left==null

2.cue.right==null

3.最复杂的情况 cur.left!=null&&cur.right!=null

6 性能分析

7 和 java 类集的关系

二.内部类

1.本地内部类

2.实例内部类

1.不可以定义静态 因为静态表示属于类 不属于对象的

2.如何实例内部类对象

3.如何继承内部类

4.出现与外部类同名的情况

3.静态内部类

1.可以定义静态成员

2.如何new

3.如何访问外部类成员

4.匿名内部类


一.二叉搜索树

1 概念

二叉搜索树又称二叉排序树,它或者是一棵空树**,或者是具有以下性质的二叉树:

若它的左子树不为空,则左子树上所有节点的值都小于根节点的值

若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

它的左右子树也分别为二叉搜索树

int a [] = {5,3,4,1,7,8,2,6,0,9}

2 操作-查找

public  Node search(int key){
    if(root==null) return null;
    Node cur=root;
    while(cur!=null){
        if(cur.val==key){
            return cur;
        }
        if(cur.val>key){
            cur=cur.left;
        }else{
            cur=cur.right;
        }
    }
    return null;
}

3.插入

跟查找原理类似,看跟val值大小比较.大往左走,小往右走,直到走到null了

.就可以插入,但是我们一定要知道他的父亲节点,所以我们需要定义一个后驱节点

public boolean insert(int val){
    if(root==null){
        Node root=new Node(val);
        return true;
    }
    Node pre=null;
    Node cur=root;
    while(cur!=null){
        pre=cur;
        if(cur.val>val){
            cur=cur.left;
        }else if(cur.val<val){
            cur=cur.right;
        }else{
            return false;
        }
    }//到这里就是找到对应要插入的父亲节点了
    Node node=new Node(val);
    if(pre.val>val){
        pre.left=node;
    }else{
        pre.right=node;
    }
    return true;
}

4.删除(难点)

分为多种情况 ,需要分类讨论

1.cur.left==null

直接让root指向cur.right

2.cue.right==null

跟左边是一样的

3.最复杂的情况 cur.left!=null&&cur.right!=null

是不能鲁莽直接删去.那他下面的子树怎么办

替换法

所以我们需要从他的右树找最小值或者从左子树找到最大值覆盖掉原来要删去的节点

并删去覆盖节点的原来位置

/**
 * 删除
 * @param val
 * @return
 */

public boolean remove(int val){
    if(root==null) return false;
    Node cur=root;
    Node parent=null;
    while(cur!=null){
        if(cur.val==val){
            remove1(parent,cur);
            return true;
        }else if(cur.val>val){
            parent=cur;
            cur=cur.left;
        }else{
            parent=cur;
            cur=cur.right;
        }
    }
    return false;
}
public void remove1(Node parent,Node cur){
    if(cur.left==null){
        if(cur==root){
            root=cur.right;
        }else if(cur==parent.left){
            parent.left=cur.right;
        }else if(cur==parent.right){
            parent.right=cur.right;
        }
    }else if(cur.right==null){
        if(cur==root){
            root=cur.left;
        }else if(cur==parent.left){
            parent.left=cur.left;
        }else  if(cur==parent.right){
            parent.right=cur.left;
        }
    }else{
        //从左子树找到最大值
        Node ti =cur.left;
        Node tip=cur;
        while(ti.right!=null){
            tip=ti;
            ti=ti.right;
        }
        cur.val=ti.val;//他的右边是空的
        if(ti.left==null){
            //就是两边都是空的情况
            tip.right=null;
        }else{
            //左边不是空的情况
            tip.right=ti.left;
        }
    }
}

6 性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。

对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度

的函数,即结点越深,则比较次数越多。

但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树:

7 和 java 类集的关系

TreeMap 和 TreeSet 即 java 中利用搜索树实现的 Map 和 Set;实际上用的是红黑树,而红黑树是一棵近似平衡的

二叉搜索树,即在二叉搜索树的基础之上 + 颜色以及红黑树性质验证

二.内部类

1.本地内部类

作用域:当前方法

public class TestDemo {
    public  void test(){
        class test{
            int a;
        }
    }
}

2.实例内部类

在类里定义的一个类,根其他成员同级

可以看成外部类的一个普通实例方法

1.不可以定义静态 因为静态表示属于类 不属于对象的

因为调用实例内部类需要对象,但是static不需要对象.所以不可以交互

解决方法

定义静态常量\

2.如何实例内部类对象

引用内部类的成员,直接就是内部类名字.成员即可.不需要额外加外部类

Test1 test1=new Test1();
Test1.Test2 test2=test1.new Test2();//先创建对应的实例外部类对象,再用外部类来引用

3.如何继承内部类

4.出现与外部类同名的情况

对应的字节码文件

5.如果要访问外部的'

3.静态内部类

1.可以定义静态成员

与实例内部类的区别就是静态的

2.如何new

3.如何访问外部类成员

因为外部类成员调用直接由外部类.不依赖静态内部类

解决方法

1.new一个外部类来访问

4.匿名内部类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值