赞
踩
对于单链表,由于每个结点只存储了向后的指针,到了为标志就停止了向后链的操作。这样,当我们需要找到某个结点的前驱就没办法了。如何从链表中的任一结点出发,访问到链表的全部结点?循环链表就是解决这个麻烦的重要方法。
1、定义
将单链表中终端结点的指针端由空指针改为指向头指针,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表。
为了使空链表与非空链表处理一致,通常可以设一个头结点,当然不是所有的循环链表一定要头结点。
2.特点:
循环链表和单链表的主要差异在于循环的判断条件上,单链表是判断p->next是否为空,而循环链表是p->next是否等于头结点。
在单链表中,有头结点时,访问第一个结点的时间是O(1),但要访问最后一个元素时,需要O(n)时间。
如何改进能使由链表指针访问到最后一个结点用O(1)时间呢?
方法:对于上述的循环链表进行改进,不用头指针,而使用指向终端结点的尾指针来表示循环链表。
上图循环链表,查找终端结点为O(1),而开始结点为rear->next->next,时间复杂度也是O(1)。
应用:将两个循环链表合并成一个表。
循环链表为遍历及查找尾结点带来了遍历,但是查找某个结点的直接前驱,与单链表一样,都要从头结点(或尾结点)开始,遍历整个链表,时间复杂度为O(n)。双向链表解决了这个问题,但需要付出一定的空间代价。
双向链表是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。所以双向链表结点都有两个指针域,一个指向直接前驱,一个指向直接后继。
双向链表存储结构设计:
- typedef struct DulNode
- {
- ElemType data;
- struct DulNode *prior;/*直接前驱指针*/
- struct DulNode *next;/*直接后继指针*/
- }DulNode,*DulLinkList;
既然单链表有循环结构-单向循环链表,那么双向链表也可以循环——双向循环链表。
带头结点的双向循环链表的空链表:
非空的带头结点的双向循环链表:
对于双向链表,链中的某一个结点p,它的前驱的后继,后继的前驱都是自己,
即:p->prior->next=p=p->next->prior
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。