2. 简单认识数据结构

1. 数组

1.1 数组的概念

定义:数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。

从概念中可以知道一下几点:

  • 数组是线性表。

所谓的线性表就是数据排成一排,像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。当然除了数组,链表、队列、栈等也是线性表结构

image-20221229220657323

2. 栈

栈是一种基于先进后出(FILO)的数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。

3. 队列

队列是一种基于先进先出(FIFO)的数据结构,是一种只能在一端进行插入,在另一端进行删除操作的特殊线性表,它按照先进先出的原则存储数据,先进入的数据,在读取数据时先被读取出来。

4. 链表

通过前一个节点记录后一个节点的位置形成的一条链子

image-20221229221828120 image-20221229221928465 image-20221229221946666

5. 二叉树

5.1 二叉树的特点
  • 二叉树中,任意一个节点的子节点数量要小于等于2
    • 节点: 在树结构中,每一个元素称之为节点
    • 度: 每一个节点的子节点数量称之为度
image-20230102221035527
5.2 二叉树结构图

image-20230102220444613

6. 二叉查找树

6.1 二叉查找树的特点
  • 二叉查找树,又称二叉排序树或者二叉搜索树
  • 每一个节点上最多有两个子节点
  • 左子树上所有节点的值都小于根节点的值(也可以理解为任意一个节点的左子节点都比比本节点小)
  • 右子树上所有节点的值都大于根节点的值(任意一个节点的右子节点都比比本节点大)

image-20230102221904398

6.2 二叉查找树添加节点规则
  • 小的存左边
  • 大的存右边
  • 一样的不存
image-20230102222649460

image-20230102222722532

image-20230102222811414

7. 平衡二叉树

7.1 平衡二叉树的特点
  • 二叉树左右两个子树的高度差不超过1
  • 任意节点的左右两个子树都是一颗平衡二叉树
image-20230102223606805

平衡二叉树旋转

  • 旋转触发时机

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

简单左旋,就是将根节点的右侧往左拉,原先的右子节点变成新的父节点

image-20230102224506365

二、复杂左旋

image-20230102225752833

将根节点的右侧往左拉,原先的右子节点变成新的父节点,并把多余的左子节点作为已经降级的根节点当右子节点

image-20230102225931806
7.3 右旋

简单右旋,就是将根节点的左侧往右拉,左子节点变成了新的父节点

image-20230102230502873 image-20230102230543337

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

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

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

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

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

    image-20230102232228144

再对整体进行右旋

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

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

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

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

image-20230102234445267

再对整体进行左旋

image-20230102234637743

8 . 红黑树

  • 红黑树的特点

    • 平衡二叉B树
    • 每一个节点要么是红要么黑
    • 红黑树不是高度平衡的,它的平衡是通过"自己的红黑规则"进行实现的
    8.1 红黑树的红黑规则有哪些
    1. 每一个节点或是红色的,或者是黑色的

    2. 根节点必须是黑色

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

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

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

image-20230103000847059
8.2 红黑树添加节点的默认颜色
  • 添加节点时,默认为红色,效率高
image-20230103001901183
  • 红黑树添加节点后如何保持红黑规则

    • 根节点位置
      • 直接变为黑色
    • 非根节点位置
      • 父节点为黑色
        • 不需要任何操作,默认红色即可
      • 父节点为红色
        • 叔叔节点为红色
          1. 将"父节点"设为黑色,将"叔叔节点"设为黑色
          2. 将"祖父节点"设为红色
          3. 如果"祖父节点"为根节点,则将根节点再次变成黑色
        • 叔叔节点为黑色
          1. 将"父节点"设为黑色
          2. 将"祖父节点"设为红色
          3. 以"祖父节点"为支点进行旋转

image-20230103003854852

9. 哈希值

  • 哈希值简介

    ​ 是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值

  • 如何获取哈希值

    ​ Object类中的public int hashCode():返回对象的哈希码值

  • 哈希值的特点

    • 同一个对象多次调用hashCode()方法返回的哈希值是相同的

    • 默认情况下,不同对象的哈希值是不同的。因为对象的地址值不一样

    • 而重写hashCode()方法,可以实现让不同对象的哈希值相同,进行属性比较

public class HashSetDemo2 {
    public static void main(String[] args) {
        Student student = new Student("社会龙",45);
   
        Student student2 = new Student("三藏哥",46);


        System.out.println(student.hashCode());//460141958
        System.out.println(student.hashCode());//460141958
        System.out.println(student2.hashCode());//1163157884
    }
}

运行结果

image-20230103103033597

重写hashCode()方法,可以实现让不同对象的哈希值相同

public class HashSetDemo2 {
    public static void main(String[] args) {
        Student student = new Student("社会龙",45);
        
        Student student2 = new Student("社会龙",45);


        System.out.println(student.hashCode());
        System.out.println(student.hashCode());
        System.out.println(student2.hashCode());
    }
}

运行结果

image-20230103103321447

10 哈希表结构

10.1 JDK1.8以前 数组 + 链表
image-20230103103824731
  1. 创建一个默认长度16,默认加载因为0.75的数组,数组名table
  2. 根据元素的哈希值跟数组的长度计算出应存入的位置
  3. 判断当前位置是否为null,如果是null直接存入
  4. 如果位置不为null,表示有元素,则调用equals方法比较属性值

​ 5 .如果一样,则不存,如果不一样,则存入数组,老元素挂在新元素下面

当数组里面存了16*0.75= 12个元素的时候,数组就会扩容为原先的两倍

image-20230103104502306
10.2 JDK1.8以后
  • 节点个数少于等于8个

    ​ 数组 + 链表

    image-20230103105033630
  • 节点个数多于8个

    底层结构:哈希表。(数组、链表、红黑树的结合体)。

    当挂在下面的元素过多,那么不利于添加,也不利于查询,

    所以在JDK8以后,当链表长度超过8的时候,自动转换为红黑树。存储流程不变。

image-20230103105151968

存储流程

image-20230103105524497
10.3 HashSet集合存储学生对象并遍历
  • 案例需求

    • 创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
    • 要求:学生对象的成员变量值相同,我们就认为是同一个对象

情况一,Student没有重写hashCode方法


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

        HashSet<Student> students = new HashSet<>();

        Student student = new Student("社会龙",45);
        Student student2 = new Student("社会龙",45);
        Student student3 = new Student("三藏哥",46);

        students.add(student);
        students.add(student2);
        students.add(student3);

        for (Student stu : students) {
            System.out.println(stu);
        }

    }
}

运行结果

image-20230103110922186

原理分析

image-20230103110341798

重写hashcode方法,运行结果

image-20230103111223200

=“image-20230103110922186” style=“zoom: 67%;” />

原理分析

image-20230103110341798

重写hashcode方法,运行结果

image-20230103111223200
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糖分你俩颗~~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值