循环链表
1.不同与单循环链表,链表最后一个元素的的指针域不为NULL,指向头节点。
判别条件:单链表:p!=NULL;
循环链表:p!=L;
优点:从任何一个节点开始,可以遍历整个链表;
带尾指针的两个循环链表合并
Ta,Tb,P分别为A,B两个链表的尾指针与指针。
p=Ta->next; //Ta->next为A链表的头节点,将头节点的位置存在P
Ta->next=Tb->next->next; //将Tb的首元节点连接到Ta表尾(Tb的头节点不接入)
free(Tb->next); //释放Tb的头节点;
Tb->next=p;//将B表尾指针连接到p暂存的头节点的地址,实现循环;
双向链表
每个节点有三个部分,指向前继节点的指针,数据域,指向后继节点的指针;
表尾元素指向下一个元素的指针指向头节点。
1.插入
插入指针p所指的节点之前;
s=(int *)malloc(sizeof*(int));//生成新节点
s->data=e; //输入数值;
s->prior=p->prior; //将p的前继节点赋值给s的前继;
p->prior->next=s;//将p前继节点的后继指向s;
s->next=p;//s的后继指向p;
p->prior=s;//p的前继指向s;
(双循环插入时改变四个指针为插入位置前继节点的后继,后继节点的前继以及插入节点本身的两个指针;时间复杂度为O(1);但是同样在查找插入点的时间复杂度为O(n);
2.删除
p->prior->next=p->next;//p为被删除节点,前继节点的后继指向被删节点的后继节点;
p->next->prior=p->prior;//被删节点的后继节点前继指向被删节点的前继节点;
此语句时间复杂度为O(1),但是在查找被删除的节点的语句的时间复杂度为O(n)。