循环链表
如下图,将单链表中终端节点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头相接的单链表称为单循环链表,简称循环链表:
循环链表和单链表的主要差异在于循环判断上 ,原来判断p->next是否为空,现在判断p->next是否为头结点。
在单链表中,我们有了头结点,可以用 O(1)时间访问到第一个结点,访问最后一个结点需要O(n)时间(需要将单链表全部扫描一遍)。
增加了尾指针:
终端节点用尾指针rear指示,则查找终端节点时O(1),开始的节点则可以这样表示 a1= rear->next->next.
两个循环链表链接在一起时的操作:
p= rearA->next;//保存A的头结点
rearA->next = rearB->next->next;//将本是指向B表的第一个结点(不是头结点) 赋值给rearA->next
rearB->next = p;/将原A表的头结点赋值给rearB->next
free(p);// 释放p
如图:
双向链表
双向链表实在单链表的每个结点中,在设置一个指向前驱结点的指针域。
typedef struct DulNode{
int data;
struct DulNode *prior;
struct DulNode *next;
}DulNode ,&DuLinkList;如下图:
对于链表中的某一个结点p:
p->next->prior = p = p->prior ->next;
当插入存储元素为e的节点为s,步骤为下:
s->prior = p;//把P赋值给s的前驱
s->next = p->next;//把p->next 赋值给s的后继
p->next->prior = s;//把s赋值给p->next的前驱
p->next = s;//把s赋值给p的后继
如图:
删除某一个结点P需要进行一下操作:
p->prior->next = p->next;
p->next->prior =p->prior;
free(p);
如图: