八大数据结构

分类

数据结构指的是相互存在一种或多种关系的数据元素的集合,和该集合里面的元素之间的关系组成

常用的数据结构有:数组、栈、链表、队列、树、图、堆、散列表

在这里插入图片描述


数组

在这里插入图片描述

可以看做是一个大盒子里装着几个小盒子,每个小盒子里装着数据,每个小盒子有顺序排列,每个都有编号(下标),从0开始,一旦声明了大盒子的大小(能装几个小盒子)就无法再进行扩容了,通过每个小盒子的编号很容易找到小盒子的位置,也可以轻松的拿到数据,我们在对小盒子进行查询,的操作时,比较方便,但是在进行添加或者删除的操作时,我们添加一个小盒子,需要去移动其他小盒子腾地方,删除同理,也需要移动其他小盒子进行补位

通过上述的内容,记录一下数组的优缺点:

  • 优点
    • 按照索引查询元素快
    • 按照索引遍历数组比较方便
  • 缺点
    • 数组的大小固定之后就没有办法进行扩容
    • 数组只能存储一种数据类型
    • 添加,删除慢,因为要移动其他元素

适用场景:频繁查询,对于存储空间要求不大,很少增加、删除


在这里插入图片描述

适用场景为:实现递归功能,但是要注意,我们倒进去的水,要喝掉,如果不喝掉接着往里面倒的话,水就会溢出来,这也就是我们所说的栈溢出


队列

在这里插入图片描述

适用场景:因为先进先出的特点,所以一般适用于多线程阻塞队列


链表

在这里插入图片描述

单向链表:

​ 单链表就好像去寻宝,最开始拿着一个地图(头指针),指向了一个宝藏,到那里之后,发现这个宝藏里面不但有宝贝(数据域),还有一个地图(指针域),于是就跟着地图去下一个地方,下一个地方与这个地方情况一样,直到最后一个宝藏的中的地图上面什么都没有(null)——意思就是你只能跟着指针向后走

循环链表:

​ 循环链表也像去寻宝,最开始拿着一个地图(头指针),指向了一个宝藏,到那里之后,发现这个宝藏里面不但有宝贝(数据域),还有一个地图(指针域),于是就跟着地图去下一个地方,下一个地方与这个地方情况一样,直到最后一个宝藏的中的地图,地图上的地址,是你找到的第一个宝藏的地址,形成了一个循环——意思是你跟着指针走到最后就会循环回第一个数据域

双向链表:

​ 双向链表顾名思义,单项链表只跟着指针向后走,双向链表,就比较牛X了,它不但可以向后走,还能向前走?为啥它这么嚣张,因为它有两个指针域,一个指向下一个数据域,另一个就是指向上一个数据域,直至指向null为止,意思就是,你去盗墓,从第一个地图出发,找到第一个墓穴,第一个墓穴里面除了有宝藏(数据)以外还有两张地图,一张是空白的(指向null),另一张是下一个墓穴的位置,然后你去了第二个,里面跟第一个墓穴一样,一个宝藏,两张地图,不一样的是,两张地图中,一个指向上一个墓穴的位置,另一个指向了下一个墓穴的位置,你可以回去,也可以接着往下走,无论走下去,还是回去,都是直到手中的地图是空白的(指向null)为止

链表的优点:

  • 链表不需要初始化容量,可以任意加减元素
  • 添加或者删除元素时只需要改变前后两个元素结点的指针域指向地址即可,所以添加,删除很快

链表的缺点:

  • 因为含有大量的指针域,占用空间较大
  • 查找元素需要遍历链表来查找,非常耗时

适用场景:数据量小,需要频繁增加,删除


在这里插入图片描述

扩展:

我们讨论最多的就是上面的图,也是树的一种,名为二叉树,为啥叫他二叉树呢,你可以理解为,它每个节点最多能有两个字节点,意思是能最多形成两根树杈,而且每个子树是有顺序的,不能颠倒,哪怕它只有一个子树,也要区分开是左子树,还是右子树

二叉树的添加,删除元素都很快,并且在查询方面也有很多优化,所以,常用于处理数据量比较大的动态数据

二叉树有很多扩展的数据结构,比如平衡二叉树、红黑树,B+树等,比如HashMap的底层源码中用的是红黑树,MySql索引结构用的是B+树,虽然二叉树功能强大,但是算法上比较复杂


哈希表

在这里插入图片描述

举例解释:

​ 上图中的电话薄,就是以键值对的方式进行存储,姓名是键(key),电话号是值(value),如果我们存入的联系人很多的话,肯定一直往下翻着找是非常麻烦的,在我们通讯录的旁边有首字母,我们可以先通过首字母来定位,然后找到联系人姓名,从而找到联系人的电话,那旁边一排的首字母,具体是怎么做到的呢?——我们首先拿到每一个key,然后通过hash函数,取到每一个姓名的首字母存入散列表中,查询的时候,就像通讯录一样,先通过首字母找到姓名,从而使用姓名拿到电话号码,哈希表的查询也是这样的。通过key的hash值,找到对应的hash表中的Entry(键值对),比对一下key是否是一样的,如果一样的话就拿到数据了,如果不一样的话,下面会说

哈希冲突

这个问题是什么样子的呢?还是拿上面的图进行举例,我们可以看到,张三和赵六的首字母都是Z,那我们把思想放在程序上,会不会有可能出现,两个key通过Hash函数拿到了同一个Hash值,这个就叫hash冲突,那这个问题怎么解决呢?有两种办法:

  • 开放寻址法
  • 拉链法

开放寻址法:

​ 这个方法其实很好理解,就好像你去上厕所一样,第一个坑位被占用了,肯定是要看看下一个坑位是不是能用,如果不能用就接着下一个,这就叫开放寻址法,那有人可能就问了,那厕所的坑位是固定的,那如果我一个一个看下去都不能用怎么办?这个其实不用考虑,为什么呢?因为当一定量的位置被占光之后会发生扩容,这里有个增长(负载)因子的概念,当占用的位置达到总位置的百分之多少的时候,就会扩容,比如总共有10个坑位,其中7个坑位被占用之后就会发生扩容,因为它的增长因子是0.7,也就是达到总数的70%就需要扩容了

拉链法:

​ 拉链法就是使用数组,当我们的两个key的哈希值相同的时候,都要存放在第一个位置上的时候,那第一个位置上不仅仅是第一个Entry,还有一个next指针指向其他位置,如果再一样,就在第二个Entry中再放一个next指针,也指向其他位置,啥意思呢?就是还拿厕所哪个举例子吧(这是个有味道的例子🤑),有两个厕所A和B,张三去上厕所的时候,使用的是A厕所的1号坑位,李四也去了,他跟你说让你来A厕所的1号坑位给他送纸,但是那个位置现在是张三,那咋办呢?他在A厕所的1号坑位给你留了个纸条,上面写着他在B厕所的2号坑位,这个纸条就是next指针,指向了他在的位置,如果B厕所的2号坑位也被占了,那就再留纸条,你需要一个坑微一个坑位的对比,那个人是不是李四(也真是为难你了😫)


在这里插入图片描述

关于堆的性质,有一篇博客中的一个描述给我整懵了

堆中某个节点的值总是不大于或不小于其父节点的值

😨😨😨😨😨😨😨😨小小的脑袋大大的问号,什么叫某个节点的值总是不大于或者不小于其父节点的值,那如果说我有个节点的值,它不大于且不等于父节点的值,那不就说明它小于父节点的值吗?,但是又不能小于父节点的值,给我整懵了,看得我一愣一愣的,然后看了图解才大概有所领悟,在小根堆中,某个节点的值总是不小于其父节点的值,在大根堆中,某个节点的值总是不大于其父节点的值,是这个样子吗?

你k,你k你擦

堆总是一棵完全二叉树 **完全二叉树:**在满足满二叉树的性质后,最后一层的叶子节点均需在最左边


在这里插入图片描述

图是由结点的有穷集合V和边的集合E组成。其中,为了与树形结构加以区别,在图结构中常常将结点称为顶点,边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系。按照顶点的指向方向可以分为无向图和有向图

小结

博主也是正在学习,博客只为记录学习,内容来源于多个博主的博客和自己的理解,可能理解有误,如有错误,还望各位可以指正,我会及时修改,本篇的内容仅仅是对数据结构的简单理解,具体如何实现,如何使用,还得多加学习!之所以博客的风格如此怪异,因为我觉得学习其实是个很枯燥的事情,相信大多数人也是如此,我不喜欢学习,但是又不得不学,所以只能自己找方法,希望学习轻松一点,我其实很不喜欢看那些满篇晦涩难懂的文字和技术用语,很难理解,我得慢慢理解并且转化成生活中的例子去理解,内容如过引起您的不适,还请见谅😇😇😇😇😇😇
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LBK.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值