一、循环链表
优点:可以从任意一个结点出发查找其他结点
检空:判断尾指针是否指向头指针
p!=L
p->next!=L
通过头指针 H 查找an的时间复杂度为O(n)、a1的时间复杂度为O(1)
a1的存储位置为R->next->next
an的存储位置为R
通过尾指针 R 查找an、a1的时间复杂度为O(1)
将两个带尾指针的循环链表合并
LinkList Connect(LinkList Ta,LinkList Tb){
p=Ta->next;//p保存表头结点
Ta->next = Tb = next->next;//Tb表头连接Ta表尾
delete Tb->next;//释放Tb的头指针
Tb->next = p;//修改指针
return Tb;
}
时间复杂度为O(1)
二、双向循环链表(在每个结点里增加一个前驱指针域prior)
可以直接查找一个结点的前驱结点(不需要像单链表一样绕场一周)
定义
typedef struct DuLNode{
ElemType data;
sturct DuLNode *prior,*next;
}DuLNode,*DuLinkList;
双向链表具有对称性,在插入和删除时需要修改两个指针,操作的时间复杂度均为O(n)
插入
void ListInsert_Dul(DuLinkList &L,int i, ElemType e){
if(!(p=GetElemP_Dul(L,i))) return ERROR;//查找位置,如果没有直接返回错误
s= new DuLNode; s->data=e;
s->prior = p->piror; p->prior->next=s;//连接前驱元素
s->next = p; p->piror=s;//连接后继元素
return OK;
}
删除
void ListDelete_Dul(DuLink &L,int i,ElemType &e){
if(!(p=GetElemP_Dul(L,i))) return ERROR;//查找位置,如果没有直接返回错误
e=p->data;
p->prior->next = p->next;//断开前驱指针
p->next->prior=p->prior;//断开后继指针
delete p;
return OK;
}
多种链表的比较(时间复杂度)
顺序表与链表的对比