赞
踩
目录
循环单链表虽然能实现从任一结点出发沿着链找到其前驱结点,但时间耗费是O(n)。如果希望从表中快速确定一个结点的前驱,就是在单链表的每个结点中再增加其前驱的指针域prior(结点有两个指针域)。这样形成的链表中就有两条方向不同的链,称为双(向)链表(double linked list)。双向链表的结点结构如图2.14所示。
- typedet struct DNode
- { ElemType data ;
- struct DNode * prior, * next;
- } DNode,* DoubleList;
单链表类似,双向链表也可增加头结点使其运算变得方便。同时双链表也可以有循环表,称为双向循环链表,其结构如图2.15所示
双向循环链表:让头结点的前驱指针指向链表的最后一个结点 ,让最后一个结点的后继指针指向头结点
由于在双向链表中既有前向链又有后向链,寻找任一个结点的直接前驱结点与直接后继结点都变得非常方便了。设指针p指向双向链表中某一结点,则有下式成立:
(双向链表结构的对称性)
- p->prior->next==p
- p==p->next->prior
在双向链表中,那些只涉及后继指针的算法,如求表长度、取元素、元素定位等,与单链表中相应的算法相同,只是涉及前驱和后继两个指针变化的操作不同。
算法思想:要在双向链表第i个结点之前插人一个新的结点,则指针的变化情况如图 2.16 所示。
- int DlinkIns(DoubleList L,int i, ElemType e)
- {
- DNode *s,*p;
- ... /*先检查待插入的位置i是否合法(实现方法同单链表的前插操作)*/
- .../*若位置i合法,则找到第i个结点并让指针p指向它*/
- s=( DNode*)malloc(sizeof( DNode));
- if(s)
- { s->data=e;
- s->prior=p->prior; ①
- p->prior->next=s; ②
- s->next=p; ③
- p->prior=s; ④
- return TRUE;
- }
- else return FALSE:
- }

算法思想:要在双向链表第i个结点之前插入一个新的结点,则指针的变化情况如图 2.16 所示。
- int DlinkDel( DoubleList L,int i,ElemType *e)
- {
- DNode *p;
- .../*先检查待插入的位置i是否合法(实现方法同单链表的删除操作)*/
-
- .../*若位置i合法,则找到第i个结点并让指针p指向它*/
-
- *e=p->data;
- p->prior->next=p->next; ①
- p->next->prior=p->prior; ②
- free(p);
- return TRUE;
- }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。