《数据结构和Java集合框架第三版》读书笔记(六)LinkedList双向链表
2013-11-13 21:00
155 查看
JDK6和JDK7的LinkedList的算法有一些区别。JDK6是:带哨兵的环形双向链表,JDK7是不带哨兵、但是有first(头节点)和last(尾节点)的双向非循环链表。哨兵的好处是使得代码更简洁,但并不能降低对链表的操作的渐进时间界;坏处是如果有很多较短链表,使用哨兵会造成存储空间的浪费(哨兵是需要new一个Entry的)。
一,JDK6:带哨兵的环形双向链表
哨兵是个哑元,它表示NIL,包含和其他元素一样的各个域。可以简化边界条件。
private transient Entry<E>header =new Entry<E>(null,null,null);
哨兵header处于链表头和链表尾之间,哨兵的next指向链表头,哨兵的prev指向表尾,表头的prev指向哨兵,表尾的next指向哨兵。这样使得每个元素Entry对象都有一个前置Entry对象和一个后置Entry对象,从而简化了表头和表尾的边界条件,简化了链表插入和删除的代码
1,构造函数:
public LinkedList()
{header.next =header.previous =header;
}
哨兵首尾相连,形成环形链表。
2,插入元素
默认add方法在表尾添加元素。
下边这个方法更具有普遍性
在index位置插入元素element
如果index==size,则在表尾插入元素(由于环形双向链表的表尾的next是哨兵header,因此相当于在哨兵header之前插入一个元素,即addBefore(header)) 这个操作的时间复杂度可以认为是O(1)级别的
如果index不等于size,则需要entry(index)函数查找index位置的元素了。
由于这是一个环形双向链表,可以比较index和(size/2),来判断应该从header字段开始正向搜索还是逆向搜索
最坏情形是index在中间,要进行n/2次迭代(for循环次数),所以worstTime(n)为O(n)
上边那张图里entry(1)的结果,找到了“Eric”元素
addBefore方法:
准备在阶段e前插入元素为Don的新节点,创建这个新节点newEntry,将其前驱指针域指向e的前驱,后继指针域指向e
调整newEntry的前驱对象的后继指针域指向newEntry,调整newEntry的后继对象的前驱指针域指向newEntry
结果
3,删除元素
remove函数比较好写
首先要查找出节点,如果是remove(index),最坏情形迭代n/2次;如果是remove(Object),最坏情形迭代n次。总之还是O(n)
找到这个节点后,只需要改变被删除的元素的前驱对象的next和后继对象的prev就好了。这一步的操作的worstTime(n)是O(1).
总结:说LinkedList适合随机增删是有前提的,即链表不能太大。因为查找节点会耗费大量时间。
一,JDK6:带哨兵的环形双向链表
哨兵是个哑元,它表示NIL,包含和其他元素一样的各个域。可以简化边界条件。
private transient Entry<E>header =new Entry<E>(null,null,null);
哨兵header处于链表头和链表尾之间,哨兵的next指向链表头,哨兵的prev指向表尾,表头的prev指向哨兵,表尾的next指向哨兵。这样使得每个元素Entry对象都有一个前置Entry对象和一个后置Entry对象,从而简化了表头和表尾的边界条件,简化了链表插入和删除的代码
1,构造函数:
public LinkedList()
{header.next =header.previous =header;
}
哨兵首尾相连,形成环形链表。
2,插入元素
默认add方法在表尾添加元素。
下边这个方法更具有普遍性
在index位置插入元素element
public avoid add(int index,Object element){ addBefore(element,(index==size?header:entry(index))); }
如果index==size,则在表尾插入元素(由于环形双向链表的表尾的next是哨兵header,因此相当于在哨兵header之前插入一个元素,即addBefore(header)) 这个操作的时间复杂度可以认为是O(1)级别的
如果index不等于size,则需要entry(index)函数查找index位置的元素了。
由于这是一个环形双向链表,可以比较index和(size/2),来判断应该从header字段开始正向搜索还是逆向搜索
最坏情形是index在中间,要进行n/2次迭代(for循环次数),所以worstTime(n)为O(n)
上边那张图里entry(1)的结果,找到了“Eric”元素
addBefore方法:
准备在阶段e前插入元素为Don的新节点,创建这个新节点newEntry,将其前驱指针域指向e的前驱,后继指针域指向e
调整newEntry的前驱对象的后继指针域指向newEntry,调整newEntry的后继对象的前驱指针域指向newEntry
结果
3,删除元素
remove函数比较好写
首先要查找出节点,如果是remove(index),最坏情形迭代n/2次;如果是remove(Object),最坏情形迭代n次。总之还是O(n)
找到这个节点后,只需要改变被删除的元素的前驱对象的next和后继对象的prev就好了。这一步的操作的worstTime(n)是O(1).
总结:说LinkedList适合随机增删是有前提的,即链表不能太大。因为查找节点会耗费大量时间。
相关文章推荐
- C#2008与.NET 3.5 高级程序设计读书笔记(32)-- ASP.NET Web控件、主题和母版页
- MDX Step by Step 读书笔记 - 个人专题(一) 如何理解 MDX 查询中WHERE 条件如何对应Cube 中的切片轴 Slicer Axis
- 《C++程序设计原理与实践》读书笔记(二)
- IPC机制———读书笔记
- 《如何阅读一本书》读书笔记
- 《大话设计模式》读书笔记-第4章 开放-封闭原则
- 【CLRS】《算法导论》读书笔记(四):栈(Stack)、队列(Queue)和链表(Linked List)
- 『重构--改善既有代码的设计』读书笔记----Move Method
- 【读书笔记】【Android 开发艺术探索】第4章 View 的工作原理
- 《UNIX环境高级编程》读书笔记之系统数据文件和信息(1)
- FPGA/CPLD与ASIC设计流程——《Verilog与数字ASIC设计基础》读书笔记(三)
- 《程序员修炼之道》读书笔记
- 敏捷开发读书笔记
- <松本行弘的程序世界> 读书笔记
- 《领域驱动设计》读书笔记(6)——隐含概念转变为显式概念
- 读书笔记之编程之美 - 4.1 金刚坐飞机问题
- 现在操作系统-第二章读书笔记2.1
- 【读书笔记《Android游戏编程之从零开始》】12.游戏开发基础(Canvas 画布)
- 【java读书笔记】JSTL,快速精通
- 《java并发编程实战》读书笔记10--显示锁Lock,轮询、定时、读写锁