2.6循环单链表
单链形式的循环链表结构是首尾相接的单链表,即最后一个结点的指针指 向链表的表头结点或第一个结点。
判别当前结点 p 是否为循环单链表 L 的表尾结点的判别条件: p->next!=L, 即 p->next 是否指回到头,与一般单链表 p->next 是否为 NULL 不同。 在循环单链表中,也可只设置一个头结点,这样,空循环链表仅由一个自成循环的头结点表示。
循环链表:
- 定义: 即首尾相接的链表。
- 结构: 尾结点的指针域指向头结点或表的首元结点;
- 特点:表中所有结点都链接在一个环上。
循环单链表的合并算法:
【算法思想】
- 遍历两链表找表尾;
- 将第一表尾链接第二表头,将第二表尾链接第一表头;
【算法步骤】
- 1.设置指针 p,q 从头遍历查找两链表的表尾;
- 2.修改第一表的尾指针,使其指向第二表的头结点;
- 3.修改第二表的尾指针,使其指向第一表的头结点;
循环单链表的合并算法举例:
有两个带头结点的循环单链表 LA、LB,设计算法,将两个循环单链表合并为一 个循环单链表,其头指针为 LA。
【算法描述】
LinkList merge_1(LinkList LA,LinkList LB)
{ /*此算法将两个采用头指针的循环单链表的首尾连接起来*/
Node *p, *q;
p=LA;
q=LB;
while (p->next!=LA) p=p->next; /*找到表 LA 的表尾,用 p 指向它*/
while (q->next!=LB) q=q->next; /*找到表 LB 的表尾,用 q 指向它*/
q->next=LA; /*修改表 LB 的尾指针,使之指向表 LA 的头结点*/
p->next=LB->next; /*修改表 LA的尾指针,使之指向表 LB 中的第一个结点*/
free(LB);
return(LA);
}
采用上面的方法,需要遍历链表,找到表尾,其执行时间是 O (n)。
若单循环链表设置尾指针表示,在实现上述合并时,无需循环遍历找尾结点, 只需要直接修改尾结点的指针域,其执行时间是 O(1)。
【算法描述】
LinkList merge_2(LinkList RA,LinkList RB)
{ /*此算法将两个采用尾指针的循环链表首尾连接起来*/
Node *p;
p=RA->next; /*保存链表 RA 的头结点地址*/
RA->next=RB->next->next;/*链表 RB 的开始结点链到链表 RA 的终端结 点之后*/
free(RB->next);/*释放链表 RB 的头结点*/
RB->next=p;/*链表 RA 的头结点链到链表 RB 的终端结点之后*/
return RB;/*返回新循环链表的尾指针*/
}