数据结构-链表结构分析(LinkedList)。

xiaoxiao2025-08-06  24

转载请注明作者:Edison丶梦楠

如有错误之处,还请您务必在留言区留下您的宝贵经验。或发送邮箱:mvpxiaonan@foxmail.com 告知。

本人非常感谢!希望能和您共同学习,共同进步!

下面介绍链表的两种结构:

单向链表:只能从头遍历到尾,或者从尾遍历到头。

图例:

next:获取下一个节点。

ele:每个节点中的元素。

first:指头部,链表中第一个元素。

我们可以理解为,当拿到链表对象,调用first()就可以得到第一个元素。

size:指元素的个数。(或链表的长度-1,索引从0开始),在集合中没有length一说。数组中的length相当于集合框架中的size

 

模拟代码为:

//单向链表 class Node{ Node next: //下一个节点 声明方法 Object ele: //节点中的数据 声明方法 public static void main(String [] Nodetest){ Node cnode = new Node(); cnode.next(); //获取下一个元素 cnode.ele(); //获取当前节点元素。 cnode.next().ele(); //获取下一个节点中的元素 } }

 

双向链表:可以从头遍历到尾,也可以从尾遍历到头。

我们可以理解为,双向链表其实就是两个单向链表的合成。只不过是一个从头到尾,一个从尾到头。

 

图例:

 

prev:表示上一个节点

Node first:拿到第一个节点

Node last:拿到最后一个节点。

 

模拟代码:

//模拟双向链表代码 class Node{ Node first: //第一个节点 声明方法 Node last: //最后一个节点 声明方法 Node prev: //上一个节点 Node next: //下一个节点 声明方法 Object ele: //节点中的数据 声明方法 public static void main(String [] Nodetest){ Node cnode = new Node(); cnode.next(); //获取下一个节点 cnode.ele(); //获取当前节点元素。 cnode.next().ele(); //获取下一个节点中的元素 cnode.first(); //获取第一个节点 cnode.last(); //获取最后一个节点 cnode.prev(); //获取上一个节点 } }

 

基于链表的实现代码:

//基于双向链表的集合 /** *具体操作代码请参见LinkedList源码 *这里不作具体实现 */ pub11c class MyLinkedL1st { private Node first;//链表的第一个节点 private Hode last;//链表的最后一个节点 private int s1ze;//节点的数量 //链表中的每一个节点 class Node { Node prev;//上一个节点对象 Node Next;//下一个节点对象 Object ele;//当前节点中存储的元素 } }

 

总结:对于链表操作,无疑是双向链表功能更强大。而双向链表在取头和尾的时候速度更快。

对于链表LinkedList的具体实现,我们仔细读源码可以得出:

在删除操作上,链表结构相对于数组结构要更快。

为什么呢?

数组每次进行删除操作都要进行移位与遍历。当某个元素被删除时,后面的元素要向前补位。最后一个元素设为null,

然后再删除最后一个元素所占的内存空间。  

 

链表的删除操作算法分析:

删除(first也可当做current)即第一个节点时,把下一个节点的next赋给第一个节点的next。把第一个节点的prev设为null;

 

删除最后一个节点时,把最后一个节点的prev赋给当前对象的last,再把current节点的上一个(prev)节点的next设为null;

 

删除中间(此处中间节点指将要被删除的节点current)节点时,把current节点的next赋给current节点的上一个节点的next。

再把current节点的prev赋给current节点的下一个节点的prev。

 

下面给出具体实现代码:

 

前文说过,LinkedList在向头和尾添加元素时,性能更优。下面给出具体实现代码及代码分析:

在向头部添加元素时算法实现:

把新增之前第一个节点设为新增节点的next节点,然后把新增节点作为之前第一个节点的上一个节点。(或换种说法:把之前第一个节点的上一个节点作为新增节点),再把新增节点作为第一个节点。而新增节点的prev最好设置为null

 

 

向尾部添加元素算法实现:

把新增节点作为之前最后一个节点的next节点,再把之前最后一个节点作为新增节点的上一个节点。

再把对象的last属性设置为新增节点即可。

 

 

 

      对LinekdList操作的性能分析:

 

     1):增操作:

      双向链表可以直接获取自己的第一个和最后一一个节点,

      如果新增的元素在第一个或最后一 个位置,那么操作只有1次.

 

      2):删除操作(removeFisrt,removelast):

      如果删除第一个元素:操作一一次.如果操作最后一个元素:操作一次如果删除中间的元素:

      找到元素节点平均操作:(1+N)/2次.找到节点之后做删除操作: 1次

     3):查询操作:

      平均:(N+1)/2次

    4):修改操作:

      平均:(N+1)/2+1次  

 

基于前文(ArrayList性能分析),我们可以得出ArrayList和LinkedList的各自优异之处。基于数组的列表和基于链表的列表的性能对比:                                                                     Arraylist:查询,更改较快,新增和刪除较慢                                                                     Linkeduist查询更改较慢,新增和删除较快

 

 

 

转载请注明原文地址: https://www.6miu.com/read-5034359.html

最新回复(0)