|
|
|
|
移动端

3.2.2 简单链表

《数据结构与算法分析:Java语言描述(原书第3版)》第3章表、栈和队列,本章讨论最简单和最基本的三种数据结构。实际上, 每一个有意义的程序都将显式地至少使用一种这样的数据结构, 而栈则在程序中总是要被间接地用到, 不管我们在程序中是否做了声明。本节为大家介绍简单链表。

作者:冯舜玺/陈越 译来源:机械工业出版社|2016-04-13 11:56

年前最后一场技术盛宴 | 1月27日与京东、日志易技术大咖畅聊智能化运维发展趋势!


3.2.2 简单链表

为了避免插入和删除的线性开销, 我们需要保证表可以不连续存储, 否则表的每个部分都可能需要整体移动。图3-1指出链表的一般想法。

链表由一系列节点组成, 这些节点不必在内存中相连。每一个节点均含有表元素和到包含该元素后继元的节点的链(link)。我们称之为next链。最后一个单元的next链引用null。

为了执行printList或find(x), 只要从表的第一个节点开始然后用一些后继的next链遍历该表即可。这种操作显然是线性时间的, 和在数组实现时一样, 不过其中的常数可能会比用数组实现时要大。findKth操作不如数组实现时的效率高; findKth(i)花费O(i)的时间并以这种明显的方式遍历链表而完成。在实践中这个界是保守的, 因为调用findKth常常是以(按i)排序后的方式进行。例如, findKth(2),findKth(3),findKth(4)以及findKth(6)可通过对表的一次扫描同时实现。

remove方法可以通过修改一个next引用来实现。图3-2给出在原表中删除第三个元素的结果。

insert方法需要使用new操作符从系统取得一个新节点, 此后执行两次引用的调整。其一般想法在图3-3中给出, 其中的虚线表示原来的next引用。

我们看到, 在实践中如果知道变动将要发生的地方, 那么向链表插入或从链表中删除一项的操作不需要移动很多的项, 而只涉及常数个节点链的改变。

在表的前端添加项或删除第一项的特殊情形此时也属于常数时间的操作, 当然要假设到链表前端的链是存在的。只要我们拥有到链表最后节点的链, 那么在链表末尾进行添加操作的特殊情形(即让新的项成为最后一项)可以花费常数时间。因此, 典型的链表拥有到该表两端的链。删除最后一项比较复杂, 因为必须找出指向最后节点的项, 把它的next链改成null, 然后再更新持有最后节点的链。在经典的链表中, 每个节点均存储到其下一节点的链, 而拥有指向最后节点的链并不提供最后节点的前驱节点的任何信息。

保留指向最后节点的节点的第3个链的想法行不通, 因为它在删除操作期间也需要更新。我们的做法是, 让每一个节点持有一个指向它在表中的前驱节点的链, 如图3-4所示, 我们称之为双链表(doubly linked list)。


喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:342347198

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

Expert C# 2005 Business Objects中文版

本书描述了怎样应用面向对象的概念来进行.NET应用程序的架构、设计和开发。作者将重点放在了面向业务的对象,即业务对象和怎样在包括Web和...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊