首页 > 其他分享 >红黑树、HashSet、LinkedHashSet底层原理

红黑树、HashSet、LinkedHashSet底层原理

时间:2024-08-10 23:23:56浏览次数:7  
标签:LinkedHashSet Student HashSet System 哈希 红黑树 println new out

1. 数据结构(红黑树)

  • 红黑树是一种自平衡的二叉查找树,是计算机科学中用到的一种数据结构。
  • 1972年出现,当时被称之为平衡二叉B树。后来,1978年被修改为如今的”红黑树"。
  • 它是一种特殊的二叉查找树,红黑树的每一个节点上都有存储位表示节点的颜色。
  • 每一个节点可以是红或者黑;红黑树不是高度平衡的,它的平衡是通过“红黑规则”进行实现的。

平衡二叉树: 

        高度平衡。

        当左右子树高度差超过1时,通过旋转保持平衡。

红黑树:

        是一个二叉查找树:
                但是不是高度平衡的。
                条件:特有的红黑规则。

1.1 数据结构(红黑树)红黑规则

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

        根节点必须是黑色。

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

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

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

1.2 数据结构(红黑树)添加节点的规则

默认颜色:添加节点默认是红色的(效率高)

 1.3 数据结构(红黑树)添加节点的规则

        红黑树在添加节点的时候,添加的节点默认是红色的。

2. HashSet

2.1 存储字符串并遍历

利用Set系列的集合,添加字符串,并使用多种方式遍历。

        迭代器

        增强for

        Lambda表达式

import java.util.HashSet;
import java.util.Set;

public class A01_SetDemo1 {
    public static void main(String[] args) {
       /*
           利用Set系列的集合,添加字符串,并使用多种方式遍历。
            迭代器
            增强for
            Lambda表达式

        */


        //1.创建一个Set集合的对象
        Set<String> s = new HashSet<>();

        //2,添加元素
        //如果当前元素是第一次添加,那么可以添加成功,返回true
        //如果当前元素是第二次添加,那么添加失败,返回false
        s.add("张三");
        s.add("张三");
        s.add("李四");
        s.add("王五");

        //3.打印集合
        //无序
        //System.out.println(s);//[李四, 张三, 王五]

        //迭代器遍历
       /* Iterator<String> it = s.iterator();
        while (it.hasNext()){
            String str = it.next();
            System.out.println(str);
        }
*/

        //增强for
       /* for (String str : s) {
            System.out.println(str);
        }*/

        // Lambda表达式
        s.forEach( str->System.out.println(str));


    }
}

2.2 HashSet底层原理

  •  HashSet集合底层采取哈希表存储数据
  •  哈希表是一种对于增删改查数据性能都较好的结构

2.3 哈希表组成

  • JDK8之前:数组+链表
  • JDK8开始:数组+链表+红黑树

2.4 哈希值

哈希值:对象的整数表现形式

  •  根据hashCode方法算出来的int类型的整数
  • 该方法定义在Object类中,所有对象都可以调用,默认使用地址值进行计算
  • 一般情况下,会重写hashCode方法,利用对象内部的属性值计算哈希值

2.5 对象的哈希值特点

  • 如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
  • 如果已经重写hashcode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的
  • 在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也有可能一样。(哈希碰撞)
public class A02_HashSetDemo1 {
    public static void main(String[] args) {
        /*
            哈希值:
                对象的整数表现形式
                1. 如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
                2. 如果已经重写hashcode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的
                3. 但是在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也有可能一样。(哈希碰撞)

         */

        //1.创建对象
        Student s1 = new Student("zhangsan",23);
        Student s2 = new Student("zhangsan",23);

        //2.如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
        //  如果已经重写hashcode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的
        System.out.println(s1.hashCode());//-1461067292
        System.out.println(s2.hashCode());//-1461067292


        //在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也有可能一样。
        //哈希碰撞
        System.out.println("abc".hashCode());//96354
        System.out.println("acD".hashCode());//96354

    }
}

2.6 HashSetJDK8以前底层原理

        创建一个默认长度16,默认加载因为0.75的数组,数组名table

        根据元素的哈希值跟数组的长度计算出应存入的位置

        判断当前位置是否为null,如果是null直接存入

        如果位置不为null,表示有元素,则调用equals方法比较属性值

        一样:不存           不一样:存入数组,形成链表

                JDK8以前:新元素存入数组,老元素挂在新元素下面

                JDK8以后:新元素直接挂在老元素下面

        int index=(数组长度-1)& 哈希值

2.7 HashSet底层原理

        JDK8以后,当链表长度超过8,而且数组长度大于等于64时,自动转换为红黑树

        如果集合中存储的是自定义对象,必须要重hashCode和equals方法

利用HashSet集合去除重复元素

        需求:创建一个存储学生对象的集合,存储多个学生对象。

        使用程序实现在控制台遍历该集合。

        要求:学生对象的成员变量值相同,我们就认为是同一个对象。

import java.util.HashSet;
public class A03_HashSetDemo2 {
    public static void main(String[] args) {
        /* 需求:创建一个存储学生对象的集合,存储多个学生对象。
            使用程序实现在控制台遍历该集合。
            要求:学生对象的成员变量值相同,我们就认为是同一个对象


        String   Integer
*/
        //1.创建三个学生对象
        Student s1 = new Student("zhangsan",23);
        Student s2 = new Student("lisi",24);
        Student s3 = new Student("wangwu",25);
        Student s4 = new Student("zhangsan",23);


        //2.创建集合用来添加学生
        HashSet<Student> hs = new HashSet<>();

        //3.添加元素
        System.out.println(hs.add(s1));
        System.out.println(hs.add(s2));
        System.out.println(hs.add(s3));
        System.out.println(hs.add(s4));

        //4.打印集合
        System.out.println(hs);
    }
}
import java.util.HashSet;
public class A03_HashSetDemo2 {
    public static void main(String[] args) {
        /* 需求:创建一个存储学生对象的集合,存储多个学生对象。
            使用程序实现在控制台遍历该集合。
            要求:学生对象的成员变量值相同,我们就认为是同一个对象


        String   Integer
*/
        //1.创建三个学生对象
        Student s1 = new Student("zhangsan",23);
        Student s2 = new Student("lisi",24);
        Student s3 = new Student("wangwu",25);
        Student s4 = new Student("zhangsan",23);


        //2.创建集合用来添加学生
        HashSet<Student> hs = new HashSet<>();

        //3.添加元素
        System.out.println(hs.add(s1));
        System.out.println(hs.add(s2));
        System.out.println(hs.add(s3));
        System.out.println(hs.add(s4));

        //4.打印集合
        System.out.println(hs);
    }
}

3. LinkedHashSet底层原理

        有序、不重复、无索引。

        这里的有序指的是保证存储和取出的元素顺序一致。

        原理:底层数据结构是依然哈希表,只是每个元素又额外的多了一个双链表的机制记录存储的顺序。

 

import java.util.LinkedHashSet;
public class A04_LinkedHashSetDemo {
    public static void main(String[] args) {
        //1.创建4个学生对象
        Student s1 = new Student("zhangsan",23);
        Student s2 = new Student("lisi",24);
        Student s3 = new Student("wangwu",25);
        Student s4 = new Student("zhangsan",23);


        //2.创建集合的对象
        LinkedHashSet<Student> lhs = new LinkedHashSet<>();


        //3.添加元素
        System.out.println(lhs.add(s3));
        System.out.println(lhs.add(s2));
        System.out.println(lhs.add(s1));
        System.out.println(lhs.add(s4));

        //4.打印集合
        System.out.println(lhs);
    }
}

标签:LinkedHashSet,Student,HashSet,System,哈希,红黑树,println,new,out
From: https://blog.csdn.net/Directionboy/article/details/141097693

相关文章

  • HashMap 中处理哈希冲突,红黑树对于没有实现 Comparable 接口的 Key 处理
    背景:假设有两个对象,分别是stu和teach(都没有实现Comparable接口),将它们添加进去HashMap里,假设这两个对象发生哈希冲突,那么红黑树怎么判断它们谁在左谁在右?依据是什么?​ 当两个对象stu和teach的哈希值相同,且它们没有实现Comparable接口时,Java8的HashMap会使用t......
  • 了解红黑树:高效平衡二叉搜索树
    红黑树的概念红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。红黑树的性质每个结点不是红色就是黑色根节......
  • JavaDS —— 红黑树
    前言还是一样,这里的红黑树重点讲述插入代码的实现,如果对红黑树的删除感兴趣,可以去翻阅其他资料。在数据结构专栏中已经对AVL树的旋转调整做了分析和讲解,这里红黑树也会使用到旋转调整的代码,就不讲述旋转代码的实现,大家如果对旋转不熟悉,可以打开这个文章JavaDS——AVL......
  • 【C++/STL】map和set的封装(红黑树)
     ......
  • Java集合:Collection and Map;ArrayList;LinkList;HashSet;TreeSet;HashMap;TreeMap;Iterator:
        集合介绍:                        是一组变量类型(容器),跟数组很像。一,引用集合的原因(必要性):                  A:数组的空间长度固定,一旦确定不可以更改。多了浪费,少了报错。          B:使用数......
  • 【C++】红黑树
     ......
  • 【C++】————红黑树
                                 作者主页:   作者主页                           本篇博客专栏:C++                ......
  • 数据结构—红黑树
    红黑树的概念红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。红黑树的性质每个结点不是红色就......
  • C++ 红黑树
    1. 红黑树的概念红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。红黑树的性质......
  • 【C++深度探索】AVL树与红黑树的原理与特性
    ......