线性表的链式存储结构
查看ArrayList的源码回忆顺序存储结构:
其中核心的成员变量就是标准的顺序存储结构:
其中我们经常构造它是都会采用默认的构造方法,所以瞅一眼它:
其中:
对于它里面的方法经常使用的是往里面添加元数,如下:
另外这块考虑到了数组的扩容:
也就是用当前的总数组的长度再增加一个来进行扩容的处理,下面看一下该扩容的具体细节:
另外我们还可以在某个位置上添加数据,所以看一下它的实现逻辑:
接着就直接将元素添加在指定的位置,可见添加数据对于数组来说成本是比较高的。
链式存储结构:
定义:
线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。
种类:
1、单链表:
应用:
1、MessageQueue:
它的应用为MessageQueue,其中表现为插入消息enqueueMessage(Message msg, long when)和删除消息next()。
在Android中利用了单链表结构的有Handler机制中的Message,打开瞅一下:
而对于单链表的操作则是放在了MessageQueue中,先来看一下往它里面增加一个Message是如何做的?
接下来看一下是如何存放新加入的Message的:
此时链表的结构为:
此时就准备要插入我们的message对象了:
这就是典型的单链表的插入方式,可见插入效率也是非常高的。
接下来再来看一下里面如何删除Message的:
如图:
然后:
而如果msg的prevMsg为空,则:
2、麻将排序【像玩网上的打麻将发了牌之后隔几秒则会自动将我们的牌给摆整齐】链式基数排序:
比如发了这么一排的麻将:
然后最终应该会自动排序成:
那么很显然这个数据量已经是二位数了,上节学的冒泡和选择排序都没法弄,这里就可以采用单向链表的思路来实现上面的排序,具体思路如下:
从上图来看很显然是用了两个链表来达到我们的最终排序目的,下面看下具体代码,先定义一个麻将类:
然后再来实现其排序算法:
然后再将不同的麻将放到不同的链表数组中,也就是如图中的这个步骤:
然后再将其连接到一起,如下:
如下:
接着再将花色分三组,如下:
代码如下:
然后再将3个组合合在一起,既为最终排序之后的结果了:
最后来验证一下结果:
结果:
以上的这个场景适合为"数据量几十个,插入操作多的情况"。
2、单循环链表:
其它的具体应用可以参考之前写过的文章:https://www.cnblogs.com/webor2006/p/7102568.html
3、双链表:
而对于它的典型应用就是LinkedList,它的底层就是用的双向链表来实现的,大致瞅一下:
所以,咱们手写一个自己的简单版的LinkedList来体现双向链表的特点,如下:
然后定义LinkedList的头接点和尾接点,如下:
接下来则增加一个添加数据的方法:
但是此时我们没有考虑到last为null的情况,所以修改一下代码:
接下来则再增加一个往中间具体位置插入的方法:
所以先写一个查找指定位置的节点:
其实这个查找可以再优化一下:
而对于系统的LinkedList这块的实现有个小细节不一样:
有了这个辅助方法之后,接下来就可以实现我们在中间插入节点的需求了,如下:
先来做一下容错:
如果本身要加的位置就是在末尾,那:
接下来条件则就是往中间插,具体实现如下:
好,下面来调用一下:
接下来再来往指定位置插:
貌似完美的,其实是还有些小问题的,如下:
这时因为0的位置没有prev,所以需要做一下容错:
但是,还得有一句话:
好,再运行:
好,接下来再来一个删除方法,比较容易,直接看代码:
嗯~~完美了~~
4、双向循环链表:
其实它比较简单,就是有一个头尾的指向,就不多说了,只看一下它的结构图既可: