数据结构—cloneable&&二叉树

1介绍cloneable接口,并引申与它相关的知识点:
2二叉树相关知识点:
一、cloneable接口

首先强调一个问题,cloneable接口时空的,clone方法不是cloneable的方法!!!clone时object的方法,方法原型为

protected object clone () throws CloneNotSupportException

这里有两个细节,一 返回值是object; 二 类型为protected;三是抛出的异常

先说第一个,这里的object实际上是不用修改的,但我们可以思考一些java深入的东西,“协变”。

协变最直观的表现形式就是针对父类方法的重写,我们可以修改重写方法的返回值类型,但必须是父类方法返回值类型的子类。

第二个 clone方法的类型修饰符号是protected,先抛出理念,设计者不希望每个子类都简单拥有clone方法,需要使用者仔细的考量一下。

类的修饰符有两种,public和默认,public随意访问,默认只允许同包内才可以访问,或者不同包下实现继承也可以访问。

方法的修饰符有四种,从大到小依次为public,protected,默认,private

子类继承父类方法,修饰符可以不同,但是必须要比父类型的修饰符范围要宽,另外需要注意的是私有类型private除外,这个不可以被重写。

 同类同包子类同包非子类不同包子类不同包非子类
public
protected 
默认  
private    
第三个是异常抛出的规定,子类重写父类的方法,要么不跑出异常,要么抛出的异常要比父类的异常要小。这里,要么方法上抛

CloneNotSupportedException
要么什么都不写
@Override
public A clone(){
    A a=null;
    try {
        a = (A)super.clone();
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    a.age=1;
    return a;
}
clone方法需要注意的地方,1必须调用super.clone()方法返回一个新的对象,但是这里的super是object,object返回的应该也是object,但是object可以直接强制转化为A类型吗?不是会报错吗,这里还没有弄清楚。2必须捕获异常或者抛出异常。上面写的是一种标准的clone实现手段。

二、二叉树

1满二叉树:叶子节点在最底层,非叶子节点都有两个孩子

2完全二叉树:除了最后一层都是满的,最后一层从左到右填充

3平衡二叉树:每个节点左右子树的高度差不超过1

4完全平衡二叉树:每个节点有两颗高度完全相等的子树

平衡不一定完全,完全一定平衡

满二叉树的节点个树为2^h-1,因此树的深度为log(n+1),对于完全二叉树,则树深为log(n+1)向上取整。

层序遍历是广度优先,前序遍历是深度优先。

中缀表达式、前缀表达式、后缀表达式分别对应树的中序遍历、前序遍历、后序遍历

普通树转化为二叉树的核心是左孩子是第一个孩子,右孩子是第一个兄弟。

二叉树的删除比较麻烦

考虑三种情况

1叶子节点删除

2只有左孩子或右孩子

3左孩子右孩子都有,考虑删除左孩子的最右孩子

void DeleteVal(Tree root,int val){
    Tree p =root,s=root;//p->parent,s->son
    while (s.val!=val&&s!=null){//找到要删除的元素
        if (val<s.val){
            p=s;
            s=s.left;
        }else{
            p=s;
            s=s.right;
        }
    }
    if (s==null){//如果要删除的是null,返回
        System.out.println("no point");
        return;
    }
    if (s.left==null&&s.right==null){//第一种情况,叶子节点,直接删除,父节点指向空
        if (s==root){
            root=null;//如果s是根结点,删除根结点
        }else {
            //判断叶子节点是父节点的左孩子还是右孩子
            if(p.left==s)p.left=null;
            else p.right=null;
        }
    }else if (s.left==null||s.right==null){//第二种情况,只有一个孩子
        if (s.left!=null){//只有左孩子
            if (root==s)root=s.left;//判根
            else{
                //如果删除节点是左孩子,父节点的左指针指向左孩子的左孩子
                if (p.left==s)p.left=s.left;
                //如果右孩子,父节点的右指针指向右孩子的左孩子
                else p.right=s.left;
            }
        }else {//只有右孩子
            if (root==s)root=s.right;
            else{
                if (p.left==s)p.left=s.right;
                else p.right=s.right;
            }
        }
    }else if (s.left!=null&&s.right!=null){//第三种情况
        Tree np=s;
        Tree n=s.right;
        while (n.left!=null){//找到右孩子的最左节点
            np=n;
            n=n.left;
        }
        s.val=n.val;//值替换
        if (s==np)s.right=n.right;//如果右孩子没有左孩子,直接替换
        else np.left=n.right;//如果右孩子有左孩子,删除左孩子
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值