从零开始学Java-数据结构

49 阅读12分钟
  • 那什么是数据结构呢?有的人就会说了:

image.png

其实不是的,下面我们一起来学习一下吧:

数据结构概念

  • 数据结构是计算机存储、组织数据的方式。
  • 数据结构是为了更加方便的管理和使用数据,需要结合具体的业务场景来进行选择。
  • 一般情况下,精心选择的数据结构可以带来更高的运行或者存储效率。

目录

  1. 队列
  2. 数组
  3. 链表

下面我们一起来学习一下吧:

或许我们都知道什么栈,但是在我分析这篇文章的时候,我还是不禁陷入了深思,什么是栈?从线性表的角度来讲,什么是栈?

栈,是限定仅在表尾进行插入和删除操作的线性表。

  • 栈的特点:后进先出,先进后出

从这段话中,我们就能看出,栈在线性表结构的基础上做了什么限制,栈是只能在表尾进行操作的线性表。如图所示:

image.png

  • 数据进入栈的过程称为:压/进栈
  • 数据出栈的过程称为:弹/出栈

队列

什么是队列?

相信很多朋友都在地铁站排过队,当我们想要进地铁的时候,我们会在地铁口排队,然后进入到地铁中。也就是说,我们如果想要进地铁站,那么我们必须在地铁口队伍最后面排队,也必须从队伍最前面进入到地铁。这就是一个典型的队列。

队列,是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

  • 队列的特点:先进先出,后进后出

image.png

  • 数据从后端进入的过程称为:入队

PixPin_2024-12-26_20-19-09.gif

  • 数据从前端采取的过程称为:出队

PixPin_2024-12-26_20-20-19.gif

数组

什么是数组?

数组是应用最广泛的数据存储结构。它被植入到大部分编程语言中。由于数组十分易懂,所以它被用来作为介绍数据结构的起步点,并展示面向对象编程和数据结构之间的相互关系。

数组优势和弊端

  • 数组的特点:
    • 内存连续存储
    • 查询速度快:查询数据通过地址值和索引定义,查询任意数据耗时相同。
  • 数组的弊端:
    • 删除效率低:要将原始数据删除,同时后面每个数据前移。
    • 添加效率低:添加位置后的每一个数据后移,在添加元素。

链表

我们知道数组是连续存储,这样一来会大大降低内存使用率,而如果采用链表的话,由于链表是采用分散存储,这样就大大提升了内存使用率,而且在数组中的元素叫做元素,而在链表中的元素叫做结点。而元素和结点的差距就在于结点不仅包括结点内容,还包括了下一个结点的地址。如图所示:

image.png

我们一起来看一下形成过程吧:

第一次创建链表的时候会有头结点和空地址:

image.png

我们来添加一个数据A:

image.png

是不是只要把头结点的下一个节点修改为新结点的地址就可以啦

我们再来添加一个数据C:

image.png

是不是重复修改下一个结点指向的新节点地址就可以啦!我们再来添加一个数据D:

image.png

这就是链表在存储数据的全部过程啦!下面我们来说一下他的特点和弊端吧!

链表优势和弊端

  • 链表中的结点是独立的对象,在内存中是不连续的,每个结点包含数据值和下一个结点的地址

  • 链表就是通过前一个结点记录后一个节点的地址形成的一条链子。

  • 链表的特点:链表增删相对快

image.png

  • 链表的弊端:查询慢,无论查询哪个数据都要从头开始找

image.png

什么是树?

树(英语:Tree)是一种抽象数据类型或是实现这种抽象数据类型的数据结构。树的每一个元素也叫结点,每一个结点都是一个独立的对象,当有很多结点的时候就会形成一棵树的结构。我们先来看一张图:

image.png

他是不是像一棵树呀。那么关于树有一些专业名词需要认识一下:

术语

  • 一棵树中,最大的节点的度称为树的度。

  • 根节点

    树顶端的节点被称为根。从根出发到达任意一个节点只有一条路径。

  • 父节点

    除了根节点之外,每个节点都可以向上找到一个唯一的节点,这个节点就是当前节点的父节点。相应的,父节点下方的就是子节点。

  • 叶子节点

    没有子节点的“光杆司令”就被称为叶子节点。

那这些是什么意思呢?我们继续来看一张图

image.png

那每个节点里面有什么结构呢:

image.png

其实每个节点都是一个独立的对象,里面不仅要存当前的数据,额外还会有父节点地址、值、左子节点地址值、右子节点地址值。

二叉查找树

  • 定义:二叉树又称二叉排序数或者二叉搜索数

什么是二叉查找树呢?我们来看一个图片:

image.png

在这棵二叉树里面,里面存储的值是没有什么规律的,所以我们就会称之为普通的二叉树。我们再来看下面这张图片:

image.png

这棵二叉树存储的值是不是就有规律呀,是不是每一个节点的左子节点都比自己小,每个右子节点都比比较大呀,我们就称之为二叉查找树

二叉树特点

  1. 每一个节点上最多有两个子节点
  2. 任意节点左子节点上的值都小于当前节点。
  3. 任意节点右子节点上的值都小于当前节点。

那他们添加节点又有什么规则呢?我们一起来看一下:

添加节点规则

  1. 小的就存左边
  2. 大的就存右边
  3. 一样的就不存 下面来看一下二叉树怎么遍历的吧:

二叉树遍历方式

  • 二叉树有四种遍历方式
  1. 前序遍历
  2. 中序遍历
  3. 后序遍历
  4. 层序遍历

下面我们就一个一个来学习吧:

  • 前序遍历

    从根节点开始,然后按照当前节点,左子节点,右子节点的顺序遍历。

    我们一起来看一下吧:

    PixPin_2024-12-28_14-11-16.gif

  • 中序遍历

    从最左边的子节点开始,然后按照左子节点,当前节点,右子节点的顺序遍历。

    我们一起来看一下吧:

    PixPin_2024-12-28_14-04-36.gif

    按照这种方式遍历我们可以发现,他遍历出来的是不是从小到大的顺序来获取的。

  • 后序遍历

    从最左边的子节点开始,然后按照左子节点,右子节点,当前节点的顺序遍历。

    我们一起来看一下吧:

    PixPin_2024-12-28_14-14-15.gif

  • 层序遍历

    从根节点开始一层一层的遍历。

    我们一起来看一下吧:

    PixPin_2024-12-28_14-15-57.gif

好啦,到这里遍历就学习完毕啦,最重要的是要重点掌握第二种,因为这种遍历出来的数据是从小到大的顺序进行排序的。

二叉树的弊端

下面我们来看一个例子:将7、10、11、12、13添加到二叉查找树中。我们是不是要先比较呀,小的存左边,大的存右边,那我们存完就会发现:

image.png

是不是好奇怪了呀,这是不是和链表差不多一样了呀。

image.png

那我这时候如果想要查询13怎么办呢?是不是要一个一个的去查。那这个时候效率不是很低了吗?那这个时候怎么办呢?

其实这个时候就可以用到了平衡二叉树。

image.png

我们下面一起来学习一下吧!

平衡二叉树

平衡二叉树也是一个二叉树。只是在二叉树的规则上又多了一条规则:任意节点左右子树高度差不超过1.

那我就在想了,平衡二叉树是怎么让他保持平衡的呢?下面我们就来学习一下他是怎么旋转机制吧:

旋转机制

其实平衡二叉树的旋转机制分为两种:左旋右旋

旋转的触发时期不是每次都旋转的,当添加一个节点之后,该树不再是一棵平衡二叉树的时候才会触发旋转机制。下面我们一起来学习吧:

  • 左旋

    • 确定支点:从添加的节点开始,不断的往父节点找不平衡的节点。
    • 步骤:
      • 1.以不平衡的点作为支点
      • 2.把支点左旋降级,变成左子节点
      • 3.晋升原来的右子节点

    PixPin_2024-12-28_14-48-50.gif

    下面我们来看个比较难一点的吧:

    • 步骤:
      • 1.以不平衡的点作为支点。
      • 2.将根节点的右侧往左拉
      • 3.原先的右子节点变成新的父节点,并把多余的左子节点出让,给已经降级的根节点当右子节点。

    PixPin_2024-12-28_14-52-45.gif

    到这里左旋就差不多学费了吧,那下面我们就来学习一下右旋吧:

  • 右旋

    右旋转是不是刚刚好就是左旋转相反呀!

    • 确定支点:从添加的节点开始,不断的往父节点找不平衡的节点。
    • 步骤:
      • 1.以不平衡的点作为支点
      • 2.把支点右旋降级,变成右子节点
      • 3.晋升原来的左子节点

    PixPin_2024-12-28_14-57-25.gif

    同样的,我们也来看一下比较难一点点的吧:

    • 步骤:
      • 1.以不平衡的点作为支点。
      • 2.将根节点的右侧往右拉
      • 3.原先的左子节点变成新的父节点,并把多余的右子节点出让,给已经降级的根节点当左子节点。

    PixPin_2024-12-28_15-00-00.gif

    到这里左旋和右旋就学习完毕啦,怎么样,你学费了吗!

下面我们来小结一下需要旋转的四种情况:

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

    例: image.png

    这个时候只需要一次右旋就可以让他保持平衡了:

    PixPin_2024-12-28_15-07-03.gif

    如果是左左这种情况的话只需要一次右旋就可以了。

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

    我们来看一个例子:

    image.png

    这个时候就需要分成两部分了:首先要把他变成左左,

    PixPin_2024-12-28_15-12-50.gif

    这个时候还需要进行整体的右旋就可以了。

    PixPin_2024-12-28_15-14-20.gif

    如果是左右这种情况的话需要先局部左旋在整体右旋就可以了。

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

    我们来看一个例子:

    image.png

    这个时候需要进行左旋让他保持平衡:

    PixPin_2024-12-28_15-18-00.gif

    如果是右右这种情况的话只需要一次左旋就可以了。

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

    我们来看一个例子:

    image.png

    这个时候是不是就和左右一样了呀,需要分成两部分了:首先要把他变成右右,

    PixPin_2024-12-28_15-20-21.gif

    这个时候还需要进行整体的左旋就可以了。

    PixPin_2024-12-28_15-22-16.gif

    如果是右左这种情况的话需要先局部右旋在整体左旋就可以了。

关于旋转的四种情况我们就学习完毕啦。下面我们来学习最难的红黑树吧!

红黑树

红黑树是一种自平衡的二叉查找树,是计算机科学中用到的一种数据结构。下面我们就来看一下他长什么样子吧:

image.png

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

每一个节点可以是红或者黑。红黑树不是高度平衡的,它的平衡是通过"特有的红黑规则"进行实现的

下面我们就来学习一下他的红黑规则吧:

红黑规则

  1. 每一个节点是红色的,或者是黑色
  2. 根节点必须是黑色
  3. 如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的
  4. 如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连的情况)
  5. 对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点;

那每个节点里面有什么结构呢:

image.png

添加节点规则

  1. 默认节点是红色的(效率高)

    1. 如果添加的节点默认是黑色的,需要调整两次。 image.png
    2. 如果添加的节点默认是红色的,只需要调整一次。 image.png
  2. 其他情况

image.png

好啦,到这里数据结构就学习完毕啦,怎么样,是不是感觉有点难呢?没关系,相信凭借你的聪明才智肯定很快就能学会的。有什么不懂的可以在评论区互相评论,我们下期不见不散哟!!!

==最后非常感谢您的阅读,也希望能得到您的反馈  ==