《大话数据结构》

双向链表

继续我们刚才的例子,你平时都是从_h海一路停留到北京的,可是这一次,你得先到北京开会,谁叫北京是首都呢,会就是多。开完会后,你需要例行公事,
走访齐个城市,此时你怎么办、


有人又出主意了,你可以先回上海,一路再乘火车走遍这几个城市,到了北京后,你再飞回上海。你会感慨,人生中为什么总会有这样出主意的人存在呢?真要气死人才行。哪来这么麻烦,我一路从北京坐火车或汽车回去不就完了吗。



对呀,其实生活中类似的小智慧比比皆是,井不会那么的死板教条。我们的单链表,总是从头到尾找结点,难道就不可以正反遍历都可以吗?当然可以,只不过需要加点东西而已。我们在单链表中,右了next指针,这就使得我们要查找下一结点的时间复杂度为O〔1〕0  p!是如果我们要查找的是上一结点的话,那最坏的时间复杂度就是o(n} f,f}}为我们每次都要从头开始遍历查找。为了克服单!却陕这一缺点,我们的老科学家们,设I E'出了双向链表。双向链表 {dnuhle linked list}是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。所以在双向链表中的结点都有两个指针域个指向肖接后继,另一个指向直接前驱。



既然单链表也可以有循环链表,那么双n1链表当然也,〕丁以是循环表。双向链表的循环带头结点七点的空链表如下图所示。


由一于.这是双向链表,}f}么对T链表中的某一个结点p,它的后继的前驱是谁?当然还是它自己。’色的前驱的后继自然也是它自己,即 这就如同上海的下一站是苏州、Ails么上海的下一站的前一站是哪里?哈哈、有点废话的感觉。双向链表是单链表中打,’展出来的结构,所以它的很多操作是和单链表相同的,比如求长度的ListLength,查找TC素的GetElern ,获得JL'索位置
的Lo}ateElem等。a}些操作都只要涉及一个方向的指针即可,另一指针多了也不能提供什么帮助。就像人生一样,想享乐就得先努力,欲收获就得付代价。双向链表既然是比单链表多了如可以反例遍历查找等数据结构,那么也就需要付出一些小的代价:在插人和删除时,需要更改两个指针变缈。插入操作时,其实并不复杂,不过顺序很重要,千万不能写反了。我们现在假设存储元素 e 的结点为,,要实现将结点 s 插入到结点 p 和 p  -> next之间需要下面几步,如下图所示:


关键在于它们的顺序,由于第2步和第3步都用到了 p -> next 如果第4步先执行,则会使得p -> next 提前变成了s,使得插入的工作完不成。所以我们不妨把上面这张图在理解的基础上记忆,顺序是先搞定S的前驱和后继,再搞定后结点的前驱,最后解决前结点的后继。如果插入操作理解了,那么删除操作,就比较简单了。



好了,简一单总结一下,双向链表相对于单链表来说,要更复杂一些,毕竟它多rprix。指针,对丁插入和删除时,需要格外小心。另外它由于每个结点都需要记录两份指针,所以在空I'n上是要占川略多一些的。不过,由i}它良好的对称性,使得对某个结点的前后结点的操作,带来厂方便,可以有效提高算法的时间性能。说白了,就是用空间来换时间。


这一章,我们主要讲的是线性表先谈了它的定义1线性表是零个或多个具有相同类型的数据元素的有限序列。然后谈了线性表的抽象数据类型,如它的一些基本操作。之后我们就线性表的两大结构做了讲述,先讲的是比较容易的顺序存储结构,指的是用一段地址连续的存储单兀依次存储线性表的数据元素。通常我们都是用数组来实现这一结构。后来是我们的重点,由顺序存储结构的插入和删除操作不方便,引出了链式存储结构。它具有不受固定的存储空间限制,可以比较快捷的插人和删除操作的特点。然后我们分别就链式存储结构的不同形式,如单链表、循环链表和双向链表做了讲解,另外我们还讲了若不使用指针如何处理链表结构的静态链表方法。总的来说,线性表的这两种结构(如图3-15一1所示)其实是后面其他数据结构的基础、把它们学明自了,对后面的学习有着至关重要的作用。




 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值