27.数据结构-二叉树

数据结构-树

TreeSet    树结构,是Set体系中的一员

ArrayList   数组结构   是List体系中的一员

LinkedList  链表结构  是List体系中额一员

3.数据结构

3.1二叉树【理解】

  • 二叉树的特点

    • 二叉树中,任意一个节点的度要小于等于2

      • 节点: 在树结构中,每一个元素称之为节点

      • 度: 每一个节点的子节点数量称之为度

  • 二叉树结构图

 

 

3.2二叉查找树【理解】

  • 二叉查找树的特点

    • 二叉查找树,又称二叉排序树或者二叉搜索树

    • 每一个节点上最多有两个子节点

    • 左子树上所有节点的值都小于根节点的值

    • 右子树上所有节点的值都大于根节点的值

  • 二叉查找树结构图

  •  

     

    二叉查找树和二叉树对比结构图 

 

 

二叉查找树添加节点规则

  • 小的存左边

  • 大的存右边

  • 一样的不存

 

 

 

3.3平衡二叉树【理解】

  • 平衡二叉树的特点

    • 二叉树左右两个子树的高度差不超过1

    • 任意节点的左右两个子树都是一颗平衡二叉树

  • 平衡二叉树旋转

    • 旋转触发时机

      • 当添加一个节点之后,该树不再是一颗平衡二叉树

    • 左旋

      • 就是将根节点的右侧往左拉,原先的右子节点变成新的父节点,并把多余的左子节点出让,给已经降级的根节点当右子节点

 

 

 

 

 

 

 

右旋

  • 就是将根节点的左侧往右拉,左子节点变成了新的父节点,并把多余的右子节点出让,给已经降级根节点当左子节点

 

 

 

 平衡二叉树和二叉查找树对比结构图

 

 左旋小结

  逆时针旋转

  右子节点变成父节点(根节点)

  原先的根节点降级变成左子节点

  将多余的左子节点出让,给降级的节点作为右子节点

右旋小结

  顺时针旋转

  左子节点变成父节点(根节点)

  原先的根节点降级变成右子节点

  将多余的右子节点出让,给降级的节点作为左子节点

平衡二叉树旋转的四种情况

  • 左左

    • 左左: 当根节点左子树的左子树有节点插入,导致二叉树不平衡

    • 如何旋转: 直接对整体进行右旋即可

 

左右

  • 左右: 当根节点左子树的右子树有节点插入,导致二叉树不平衡

  • 如何旋转: 先在左子树对应的节点位置进行左旋,在对整体进行右旋

 

 

 

右右

  • 右右: 当根节点右子树的右子树有节点插入,导致二叉树不平衡

  • 如何旋转: 直接对整体进行左旋即可

 

 

右左

  • 右左:当根节点右子树的左子树有节点插入,导致二叉树不平衡

  • 如何旋转: 先在右子树对应的节点位置进行右旋,在对整体进行左旋

 

 二叉树

二叉查找树(二叉排序树,二叉搜索树)

平衡二叉树

 

3.4红黑树【理解】

 红黑树是一种自平衡的二叉查找树,是计算机科学中用到的一种数据结构

  1972年出现,当时被称之为平衡二叉B树,后来,1978年被修改为如今的“红黑树”

  它是一种特殊的二叉查找树,红黑树的每一个节点上都有存储位表示节点的颜色

  每一个节点可以是红或者黑;红黑树不是高度平衡的,它的平衡时通过“红黑规则”进行实现的

平衡二叉树时高度平衡额:

  条件:当左右子树高度差超过1时-------------------->旋转

红黑树是一个二叉查找树

  但不是高度平衡的

  条件:自己的红黑规则   ----------------旋转

  • 红黑树的特点

    • 平衡二叉B树

    • 每一个节点可以是红或者黑

    • 红黑树不是高度平衡的,它的平衡是通过"自己的红黑规则"进行实现的

  • 红黑树的红黑规则有哪些

    1. 每一个节点或是红色的,或者是黑色的

    2. 根节点必须是黑色

    3. 如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的

    4. 如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连 的情况)

    5. 对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点

 

 

 

 

红黑树添加节点的默认颜色

  • 添加节点时,默认为红色,效率高

 

 

红黑树添加节点后如何保持红黑规则

  • 根节点位置

    • 直接变为黑色

  • 非根节点位置

    • 父节点为黑色

      • 不需要任何操作,默认红色即可

    • 父节点为红色

      • 叔叔节点为红色

        1. 将"父节点"设为黑色,将"叔叔节点"设为黑色

        2. 将"祖父节点"设为红色

        3. 如果"祖父节点"为根节点,则将根节点再次变成黑色

      • 叔叔节点为黑色

        1. 将"父节点"设为黑色

        2. 将"祖父节点"设为红色

        3. 以"祖父节点"为支点进行旋转

3.5成绩排序案例【应用】

  • 案例需求

    • 用TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩,英语成绩),并遍历该集合

    • 要求: 按照总分从高到低出现

  • 代码实现

    学生类

 

package com.itheima.treesettest;

public class Student implements Comparable<Student>{
    private String name;
    private int chinese;
    private int math;
    private int english;

    public Student() {
    }

    public Student(String name, int chinese, int math, int english) {
        this.name = name;
        this.chinese = chinese;
        this.math = math;
        this.english = english;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getChinese() {
        return chinese;
    }

    public void setChinese(int chinese) {
        this.chinese = chinese;
    }

    public int getMath() {
        return math;
    }

    public void setMath(int math) {
        this.math = math;
    }

    public int getEnglish() {
        return english;
    }

    public void setEnglish(int english) {
        this.english = english;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", chinese=" + chinese +
                ", math=" + math +
                ", english=" + english +
                '}'+"总分为"+getSum();
    }
    public  int getSum(){
        return chinese+math+english;
    }
    @Override
    public int compareTo(Student o) {
        //按照总分进行排序
        int result=this.getSum()-o.getSum();
        //次要条件
        //总分一样,就比较语文成绩
        result=result==0?this.getChinese()-o.getChinese():result;
        //语文成绩一样,就比较数学成绩
        result=result==0?this.getMath()-o.getMath():result;
        //数学成绩一样,就比较英语成绩
        result=result==0?this.getEnglish()-o.getEnglish():result;
        //成绩都一样,则按照姓名进行排序
        result=result==0?this.getName().compareTo(o.getName()):result;

        return result;
    }
}

  测试类

package com.itheima.treesettest;

import java.util.TreeSet;

public class TreeSetTest {
    public static void main(String[] args) {
        TreeSet <Student> ts=new TreeSet<>();
        Student s1=new Student("dahei",80,80,80);
        Student s2=new Student("erhei",90,90,90);
        Student s3=new Student("xiaohei",100,100,100);

        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        for (Student t : ts) {
            System.out.println(t);
        }

    }

}

  

  

 

 

       

 

posted @ 2020-11-16 22:02  星梦泪痕  阅读(104)  评论(0编辑  收藏  举报