二叉树基础+(Comparable、Compartor(增))

目录

二叉树

定义:
1. 满二叉树:深度为k,且有2^k-1个结点的二叉树,这种树的特点是每一层上的结点数都是最大结点数。

在这里插入图片描述

2. 完全二叉树:在一棵二叉树中,除最后一层外,若其余层都是满的,并且或者最后一层是满的,或者是在右边缺少连续若干结点, 具有n个结点的完全二叉树的深度为floor(log2n)+1。深度为k的完全二叉树,至少有2k-1个叶子结点,至多有2k-1个结点。
在这里插入图片描述

3. 根节点(没有父节点):图中A为根节点,B、C为A的子节点。
    叶子结点(没有子节点):图中H、I、J、F、G为叶子结点。
    B是A的子节点,是D的父节点

示例:

TwoImpl:
interface Two<T> {
    public void add(T data);

    public int size();

    public Object[] toArray();
}

class TwoImpl<T> implements Two<T> {
    private Node root;  //根节点
    private int size;
    private int footer;
    private Object[] resultData;
    @Override
    public void add(T data) {
        if (data == null) {
            return;
        }
        Node node = new Node((Comparable) data);
        if (this.root == null) {    //根节点
            this.root = node;
        } else {
            this.root.addNode(this.root, node);
        }
        ++this.size;
    }

    @Override
    public int size() {
        return this.size;
    }

    @Override
    public Object[] toArray() {
        if(this.size() == 0){
            return null;
        }
        this.footer = 0;
        this.resultData = new Object[this.size];
        this.root.toArrayNode();
        return this.resultData;
    }

    private class Node {
        private Comparable<T> data; //数据
        private Node left;      //左节点
        private Node right;     //右节点
        private Node parent;    //父节点

        public Node(Comparable<T> data) {
            this.data = data;
        }

        /**
         * this.data
         * @param parentNode  父节点
         * @param node  内部类实例(用于传递data数据)
         */
        public void addNode(Node parentNode, Node node) {
            if (this.data.compareTo((T) node.data) <= 0) {  //当前节点this.root小于传入节点
                if (this.right == null) {
                    this.right = node;
                    this.parent = parentNode;
                } else {
                    this.right.addNode(this, node);
                }
            } else {
                if (this.left == null) {
                    this.left = node;
                    this.parent = parentNode;
                } else {
                    this.left.addNode(this, node);
                }
            }
        }

        public void toArrayNode() { //中序解析
            if(this.left != null){  //把左边的数据全部取出再去右边的
                this.left.toArrayNode();
            }
        TwoImpl.this.resultData[TwoImpl.this.footer++] = this.data;
            if(this.right!=null){   //左边的数据取完后才会进入右边
                this.right.toArrayNode();
            }
        }
    }
}

public class Demo01 {
    public static void main(String[] args) {
        Two<Member> two = new TwoImpl<>();
        two.add(new Member("孙七", 27));
        two.add(new Member("赵六", 26));
        two.add(new Member("王五", 25));
        two.add(new Member("张三", 23));
        two.add(new Member("李四1", 24));
        two.add(new Member("李四2", 55));
        two.add(new Member("李四3", 40));
        two.add(new Member("李四4", 38));
        two.add(new Member("李四5", 29));
        two.add(new Member("李四6", 21));
        two.add(new Member("李四7", 19));
        two.add(new Member("李四11", 62));
        two.add(new Member("李四8", 51));
        two.add(new Member("李四9", 34));
        two.add(new Member("李四10", 56));
        two.add(new Member("李四12", 72));
        two.add(new Member("李四13", 45));
        two.add(new Member("李四14", 33));
        two.add(new Member("李四15", 31));
        System.out.println(Arrays.toString(two.toArray()));
    }
}

Member:
public class Member implements Comparable<Member> {
    private String name;
    private int age;

    public Member(String name, int age) {
        this.name = name;
        this.age = age;
    }
	
	//setter和getter方法略

    @Override
    public String toString() {
        return "name='" + name + ", age=" + age + "\n";
    }

    @Override
    public int compareTo(Member member) {
        /*
            this.age:表示第一个人的年龄
            member.age:表示第二个人的年龄
         */
            return this.age - member.age;
    }
}

结果:
//从小到大排列
 [name='李四7, age=19
, name='李四6, age=21
, name='张三, age=23
, name='李四1, age=24
, name='王五, age=25
, name='赵六, age=26
, name='孙七, age=27
, name='李四5, age=29
, name='李四15, age=31
, name='李四14, age=33
, name='李四9, age=34
, name='李四4, age=38
, name='李四3, age=40
, name='李四13, age=45
, name='李四8, age=51
, name='李四2, age=55
, name='李四10, age=56
, name='李四11, age=62
, name='李四12, age=72
]
代码中序输出解析:
进行排序利用的是年龄(age),利用递归达到最底层输出最小的数据存入Object数组内,递归结束一层一层的往上解,知道到最外一层,把左边数据存完后,递归右边二叉树,循环往复,把数据按照从小到大排完序(递归到最后一层递归结束,一层一层往上解,不会再进入相同的递归)。

(图画的有点丑)
在这里插入图片描述

数据查询:

//外部类的方法
public boolean inquire(T data) {
        //判断有没有数据,,没有返回false
        if (this.size() == 0) {
            return false;
        }
        //有数据进入inquireNode()内去查找数据
        return this.root.inquireNode(data);
    }
//内部类方法
 /**
         *获取数据
         * @param data  查询的数据
         * @return 是否存在查询的数据
         */
        public boolean inquireNode(T data) {
            //判断数据是否为根节点
            if (this.data.compareTo(data) == 0) {
                return true;
            } else {
                //当数据大于根节点时(this.data < data)
                if (this.data.compareTo(data) < 0) {
                    //判断右节点有没有值
                    if (this.right != null) {
                        //递归调用去匹配值,到最后时匹配就会在判断时不满足返回false
                        return this.right.inquireNode(data);
                    } else {
                        return false;
                    }
                } else {    //当数据小于根节点时(this.data > data)
                    //判断左节点有没有值
                    if (this.left != null) {
                        //递归调用去匹配值,到最后时匹配就会在判断时不满足返回false
                        return this.left.inquireNode(data);
                    } else {
                        return false;
                    }
                }
            }
        }

Comparable和Comparator

区别:
1. java.lang.Comparable:在类定义的时候实现的接口,该接口有一个comparTo()方法用于确认大小关系,属于类的原生支持。
2. java.util.Comparator:属于挽救器,在JDK1.8之前只有一个compare()方法有用,在JDK1.8之后扩充了许多方法,比Comparable强大。
3. 开发中仍优先使用Comparable。

Comparable的使用

1、 Number类的子类实例后可以使用compareTo()。

Integer num = 1;
//num大于5返回1,小于5返回 - 1,等于5返回0
System.out.println(num.compareTo(5));	 结果: -1

2.类的数据排序实现comparable<T(类)>。
和包装类使用compareTo()一样,只不过类要覆写了compareTo(),而包装类不要。

@Override
    public int compareTo(Score score) {	//传入的类
        if (score.score > this.score) {
            return -1;
        } else if (score.score < this.score) {
            return 1;
        }
        return 0;
    }

增加新数据排序:

public void sorts (Score[]scores){
            Score score = new Score("你好",199);
             System.out.println(score.compareTo(scores[1]));
        }

直接排序数组内的数据:Arrays.sort(类的数组实例),sort底层调用了compareTo(),所以一个类没有实现Comparable是无法使用Arrays.sort()进行排序的,Number类的子类都实现了。

Compartor的使用

类实现Compartor<T(类)>要覆写compare()。

@Override
    public int compare(Score t1, Score t2) {
        if (t1.getScore() > t2.getScore()) {
            return -1;
        } else if (t1.getScore() < t2.getScore()) {
            return 1;
        }
        return 0;
    }
	·	Score score = new Score("你好",199);
		//类的子类调用compare()
        System.out.println(score.compare(scores[0],scores[1]));
        System.out.println(score.compare(score,scores[0]));

Number类的子类中也有compare()方法一样。

		double douA = 9.9;
        double douB = 19.9;
        System.out.println(Double.compare(douA,douB));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值