您的位置:首页 > 其它

06.线性表(五)链式存储结构.循环链表与双向链表

2014-12-28 20:30 239 查看
循环链表与双向链表

转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空)

一、循环链表
1.循环链表:将单链表中终端结点的指针域由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表。

升华笔记:如何判断循环链表和单链表?
循环链表和单链表的主要差异就在于循环的判断条件上,即p->next是否为空。如果最后一个结点的指指针域p->next为空则说明该链表为单链表;如果p->next等于头结点则说明该链表为循环链表,假如终端结点的指针域rear,那么rear->next指向头结点。

2.实例:合并两个循环链表形成一个新的循环链表
(1)算法思想
假设有A、B两个循环链表,且其尾指针分别为rearA、rearB。
a.使A循环链表的尾指针rearA指向(rearA->next)B循环链表的第一个结点(非头结点);
b.使B循环链表的尾指针rearA指向(rearB->next)A循环链表的头结点,即就链接成了一个新的循环链表。
(2)源码实现
p=rearA->next; //声明一个结点,用来保存A表的头结点
rearA->next=rearB->next->next; //将本指向B表的第一个结点(不是头结点)赋值给rearA->next(原本指向A表的头结点)
rearB->next=p; //将原A表的头结点赋值给rearB->next
free(p); //释放p

二、双向链表
1.双向链表:双向链表是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。与单链表的主要区别是,双链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前驱。
2.线性表的双向链表存储结构
typedef int Elemtype
typedef struct DulNode
{
Elemtype data;
struct DulNode *prior; //直接前驱指针
struct DulNode *next; //直接后继指针
}DulNode,*DuLinkList
3.双向链表的插入操作
假设存储元素e的结点为s,要实现将结点s插入到结点p和结点p->next之间。
(1)算法思想
a.设置待插入结点s的前、后驱指向的结点;
b.设置结点p->next的前驱指向插入结点s;
c.设置结点p的后驱指向插入结点s
(2)源码实现

s->prior=p; //把p(结点)赋值给s的前驱
s->next=p->next;//把p(结点)原先下一个结点赋值给s的后驱
p->next->prior=s;//把s赋值给p(结点)原先下一个结点的前驱
p->next=s;//把s赋值给结点p的后继

注释:无论是前驱指针还是后驱指针,指向的都是结点,而非指向其他结点的前驱或后驱。



4.双向链表的删除操作
(1)算法思想
a.设置待删除节点p的上一个结点(p->prior)的后驱(p->prior->next)指向结点p的下一个结点;
b.设置待删除结点p的下一个结点(p->next)的前驱(p->next->prior)指向结点p的上一个结点;
c.释放结点p

(2)源码实现:删除结点p

p->prior->next=p->next; //把p->next赋值给p->prior的后继

p->next->prior=p->next; //把p->prior赋值给p->next的前驱
free(p);

注释:无论是前驱指针还是后驱指针,指向的都是结点,而非指向其他结点的前驱或后驱。



5.双向链表的性能分析
双向链表相对于单链表来说,由于每个结点都需要记录两分指针,所有在空间上是要占用略多一些。不过,由于它良好的对称性,使得对某个结点的前后结点的操作,带来了方便,可以有效提高算法的事件性能,即就是用空间来换时间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: