数据结构-链表结构分析(LinkedList)。
转载请注明作者:Edison丶梦楠
如有错误之处,还请您务必在留言区留下您的宝贵经验。或发送邮箱:mvpxiaonan@foxmail.com 告知。
本人非常感谢!希望能和您共同学习,共同进步!
下面介绍链表的两种结构:
单向链表:只能从头遍历到尾,或者从尾遍历到头。
图例:
next:获取下一个节点。
ele:每个节点中的元素。
first:指头部,链表中第一个元素。
我们可以理解为,当拿到链表对象,调用first()就可以得到第一个元素。
size:指元素的个数。(或链表的长度-1,索引从0开始),在集合中没有length一说。数组中的length相当于集合框架中的size
模拟代码为:
[code]//单向链表 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:拿到最后一个节点。
模拟代码:
[code]//模拟双向链表代码 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(); //获取上一个节点 } }
基于链表的实现代码:
[code]//基于双向链表的集合 /** *具体操作代码请参见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查询更改较慢,新增和删除较快
- 【数据结构】链表LinkedList分析与关键实现
- 数据结构之线性表之顺序表和链表(通过数据结构角度深入理解arrayList和linkedList的特性)
- (8) Java源码分析 ---- LinkedList (对应数据结构中线性表中的双向循环链表,JDK1.6)
- Android版数据结构与算法(三):基于链表的实现LinkedList源码彻底分析
- 【数据结构与算法基础】单链表及其应用基数排序 / Singly Linked List and radix sort
- java数据结构——LinkedList(单链表)
- 关于线性表的两种储存结构及单链表逆序解析(ArrayList和LinkedList)
- [置顶] ※数据结构※→☆线性表结构(list)☆============单向链表结构(list single)(二)
- [数据结构]02-线性结构3 Reversing Linked List
- LeetCode Linked List 数据结构-链表(题号2,19,21,24)
- nginx源码分析--链表结构体ngx_list_t
- 数据结构 PAT 02-线性结构2 Reversing Linked List 单链表实现
- python数据结构之链表(linked list)
- 用LinkedList链表模拟 堆栈、队列 两种数据结构
- Reverse Linked List链表反转问题解法分析
- 数据结构:链表(linked-list)
- Palindrome Linked List - LeetCode 判断一个链表是否是回文结构
- 数据结构与算法学习(二)链式存储结构LinkedList源码分析
- PAT 数据结构 02-线性结构1. Reversing Linked List (25)
- [转]Linux内核源码分析——list链表结构