数据结构:循环链表、双向链表和有序表

1、循环链表

循环链表(circular linked list)是线性表的另一种形式的链式存储表示。它的特点是表中最后一个结点的指针域指向第一个结点,整个链表成为一个由链指针相链接的环。对于循环链表,通常还在表中第一个结点之前“附加”一个“头结点”,并令“头指针”指向最后一个结点,以便头尾兼顾。头结点的结构和其他结点相同,一般情况下,无特殊需要头结点的数据域不存储任何信息。空表的循环链表由只含一个自成循环的头结点表示,如图 2.14所示。

在这里插入图片描述

循环链表的操作和单链表基本一致,差别仅在于算法中判别表尾的循环条件不是(顺链扫描的)指针 p 是否为 NULL,而是它是否等于头指针。循环链表可使某些操作简化。例如,将两个链表相接成一个表,需从一个链表的表尾链接到另一个链表的表头。若是单链表,为了找到其中一个链表的最后一个结点,必须从头指针起,顺链扫描,直至最后一个结点,其执行时间为 O(n)。而对循环链表作此操作时,由于它是个头尾相链接的环,两表相接仅需将一个表的表尾和另一个表的表首相接即可。如图 2.15 所示,完成这个操作仅需修改两个指针值即可,执行时间为 O(1)。

在这里插入图片描述

2、双向链表

以上讨论的链式存储结构的结点中只有一个指示直接后继的指针域 next。从任一结点出发,只能顺 next 指针往后寻查其他结点。若要寻查结点的前趋,则需从头指针出发.换句话说,在单链表中,求“后继”的执行时间为 O(1),而求“前驱”的执行时间为 O(n)。为克服单链表这种单向性的缺点,可利用双向链表(double linked list)。

顾名思义,在双向链表的结点中有两个指针域,其一指向“直接后继”,另一指向“直接前驱”,在 C 语言中可描述如下:

在这里插入图片描述
与单链表类似,双向链表也是由头指针唯一确定。增添头结点也能简化双向链表的某些操作,若将头尾结点链接起来则构成双向循环链表,如图 2.16 所示。空的双向循环链表由只含一个自成双环的头结点表示。

在这里插入图片描述
显然,在双向循环链表中进行插入或删除操作时,必须同时修改两个方向上的指针。然而,由于双向链表中每个结点都有一个指向前驱的指针,则在进行前插和删除操作时,算法中无需再用 while 语句找(插入或删除位置) p 的前驱。由此可见,结构的轻微变化有时也会影响算法的时间复杂度。算法 2.21 和算法 2.22 分别为在带头结点的双向循环链表中插入一个结点和删除一个结点的算法。图 2.17 和图 2.18 则分别显示执行这两个算法时指针修改的情况。

在这里插入图片描述
在这里插入图片描述
在本节中讨论的链表结构都按常规的做法,定义为一个指向链表中第一个结点或头结点的头指针。对于如此定义的链表结构,虽然也可以完成线性表的任何操作,但给某些“简单操作”带来不便。例如,求线性表的表长,在表中最后一个元素后面进行插入或者删除最后一个元素等,对顺序表进行这些操作的时间复杂度都是 O(1)常量级的,而对链表进行这些操作时,由于需要找到“尾结点”,致使它们的时间复杂度上升为 O(n)线性级。因此,在应用程序中,应将链表定义为包含“头指针”“尾指针”和“链表长度”3 个域的结构更为恰当,而且这些信息在链表生成的时候也就一并得到了。

3、有序表

若线性表中的数据元素相互之间可以比较,并且数据元素在线性表中依值非递减或非递增有序排列,即 ai>=ai-1或 ai<=ai-1(i=2,3,…,n),则称该线性表为有序表(ordered list)。有序表的基本操作和线性表大致相同,但由于有序表中的数据元素有序排列,因此在有序表中插入元素的操作应按“有序关系”进行。和线性表相同,有序表也可以有顺序表和链表两种存储表示方法

下列算法描述了在顺序有序表中插人一个数据元素的操作。已知有序表中数据元素依值递增排列,现要插入一个新的数据元素,则应该使插入之后的顺序表仍保持有序表的特性。由此在插入之前,首先应该通过查看比较找到元素 x 的插入位置,然后移动元素腾出空位并进行插入。假设已知有序表为(a1,a2, … ,an),则x的插入位置应该满足条件ai<=x<ai+1。
在这里插入图片描述
在这里插入图片描述
上述算法中的查找过程是从表尾向表头逆向进行的。显然,查找也可正向进行,即从表头向表尾扫描。算法的时间复杂度为 O(n),其中 n 为表长。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tyro达令

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值