线性表的链式存储结构

查看ArrayList的源码回忆顺序存储结构:

其中核心的成员变量就是标准的顺序存储结构:

线性表的链式存储结构_第1张图片

其中我们经常构造它是都会采用默认的构造方法,所以瞅一眼它:

线性表的链式存储结构_第2张图片

 其中:

线性表的链式存储结构_第3张图片

对于它里面的方法经常使用的是往里面添加元数,如下:

线性表的链式存储结构_第4张图片

另外这块考虑到了数组的扩容:

线性表的链式存储结构_第5张图片

也就是用当前的总数组的长度再增加一个来进行扩容的处理,下面看一下该扩容的具体细节:

线性表的链式存储结构_第6张图片

线性表的链式存储结构_第7张图片

线性表的链式存储结构_第8张图片

另外我们还可以在某个位置上添加数据,所以看一下它的实现逻辑:

线性表的链式存储结构_第9张图片

接着就直接将元素添加在指定的位置,可见添加数据对于数组来说成本是比较高的。

链式存储结构:

定义:

线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。

种类:

1、单链表:

线性表的链式存储结构_第10张图片

应用:

1、MessageQueue:

它的应用为MessageQueue,其中表现为插入消息enqueueMessage(Message msg, long when)和删除消息next()。

在Android中利用了单链表结构的有Handler机制中的Message,打开瞅一下:

线性表的链式存储结构_第11张图片

而对于单链表的操作则是放在了MessageQueue中,先来看一下往它里面增加一个Message是如何做的?

线性表的链式存储结构_第12张图片

线性表的链式存储结构_第13张图片

接下来看一下是如何存放新加入的Message的:

线性表的链式存储结构_第14张图片

此时链表的结构为:

线性表的链式存储结构_第15张图片

线性表的链式存储结构_第16张图片
线性表的链式存储结构_第17张图片

线性表的链式存储结构_第18张图片

此时就准备要插入我们的message对象了:

线性表的链式存储结构_第19张图片

线性表的链式存储结构_第20张图片

这就是典型的单链表的插入方式,可见插入效率也是非常高的。

接下来再来看一下里面如何删除Message的:

线性表的链式存储结构_第21张图片

线性表的链式存储结构_第22张图片

线性表的链式存储结构_第23张图片

线性表的链式存储结构_第24张图片

如图:

线性表的链式存储结构_第25张图片

线性表的链式存储结构_第26张图片

然后:

线性表的链式存储结构_第27张图片

线性表的链式存储结构_第28张图片

 而如果msg的prevMsg为空,则:

线性表的链式存储结构_第29张图片

线性表的链式存储结构_第30张图片

2、麻将排序【像玩网上的打麻将发了牌之后隔几秒则会自动将我们的牌给摆整齐】链式基数排序:

比如发了这么一排的麻将:

 然后最终应该会自动排序成:

 那么很显然这个数据量已经是二位数了,上节学的冒泡和选择排序都没法弄,这里就可以采用单向链表的思路来实现上面的排序,具体思路如下:

线性表的链式存储结构_第31张图片

从上图来看很显然是用了两个链表来达到我们的最终排序目的,下面看下具体代码,先定义一个麻将类:

线性表的链式存储结构_第32张图片

然后再来实现其排序算法:

线性表的链式存储结构_第33张图片

然后再将不同的麻将放到不同的链表数组中,也就是如图中的这个步骤:

线性表的链式存储结构_第34张图片

线性表的链式存储结构_第35张图片

然后再将其连接到一起,如下:

线性表的链式存储结构_第36张图片

如下:

线性表的链式存储结构_第37张图片

接着再将花色分三组,如下:

线性表的链式存储结构_第38张图片

代码如下:

线性表的链式存储结构_第39张图片

然后再将3个组合合在一起,既为最终排序之后的结果了:

线性表的链式存储结构_第40张图片

最后来验证一下结果:

线性表的链式存储结构_第41张图片

结果:

线性表的链式存储结构_第42张图片

以上的这个场景适合为"数据量几十个,插入操作多的情况"。

2、单循环链表:

线性表的链式存储结构_第43张图片

其它的具体应用可以参考之前写过的文章:https://www.cnblogs.com/webor2006/p/7102568.html

3、双链表:

线性表的链式存储结构_第44张图片

而对于它的典型应用就是LinkedList,它的底层就是用的双向链表来实现的,大致瞅一下:

线性表的链式存储结构_第45张图片

线性表的链式存储结构_第46张图片

所以,咱们手写一个自己的简单版的LinkedList来体现双向链表的特点,如下:

线性表的链式存储结构_第47张图片

然后定义LinkedList的头接点和尾接点,如下:

线性表的链式存储结构_第48张图片

接下来则增加一个添加数据的方法:

线性表的链式存储结构_第49张图片

但是此时我们没有考虑到last为null的情况,所以修改一下代码:

线性表的链式存储结构_第50张图片

接下来则再增加一个往中间具体位置插入的方法:

线性表的链式存储结构_第51张图片

所以先写一个查找指定位置的节点:

线性表的链式存储结构_第52张图片

其实这个查找可以再优化一下:

线性表的链式存储结构_第53张图片

而对于系统的LinkedList这块的实现有个小细节不一样:

线性表的链式存储结构_第54张图片

有了这个辅助方法之后,接下来就可以实现我们在中间插入节点的需求了,如下:

线性表的链式存储结构_第55张图片

先来做一下容错:

线性表的链式存储结构_第56张图片

如果本身要加的位置就是在末尾,那:

线性表的链式存储结构_第57张图片

接下来条件则就是往中间插,具体实现如下:

线性表的链式存储结构_第58张图片

好,下面来调用一下:

线性表的链式存储结构_第59张图片

接下来再来往指定位置插:

线性表的链式存储结构_第60张图片

貌似完美的,其实是还有些小问题的,如下:

线性表的链式存储结构_第61张图片

这时因为0的位置没有prev,所以需要做一下容错:

线性表的链式存储结构_第62张图片

但是,还得有一句话:

线性表的链式存储结构_第63张图片

好,再运行:

线性表的链式存储结构_第64张图片

好,接下来再来一个删除方法,比较容易,直接看代码:

线性表的链式存储结构_第65张图片

线性表的链式存储结构_第66张图片

线性表的链式存储结构_第67张图片

嗯~~完美了~~

4、双向循环链表:

其实它比较简单,就是有一个头尾的指向,就不多说了,只看一下它的结构图既可:

线性表的链式存储结构_第68张图片

你可能感兴趣的:(数据算法研究,链表,java,数据结构,python,算法)