数据结构学习(四)——循环单链表的操作之合并
所谓循环链表就是尾结点与头结点相连的链表,整个链表形成一个环。而对于循环链表的插入与删除运算,基本上与单链表相同,只是在判断链表是否结束有所不同。下面的代码操作实现了两个循环单链表的合并。且核心代码不多,主要是分别找到循环单链表的尾结点再进行后续操作。
#include <stdio.h>
#include <stdlib.h>
typedef struct list
{
char data;
struct list *next;
}linklist;
linklist *CreateLinklist_End(int *l); //尾插法创建单循环链表
linklist *Linklist_Connect(linklist *h1,int l1, linklist *h2, int l2); //单循环链表的合并
void ShowLinklist(linklist *h); //输出显示链表
int main(void)
{
linklist *head1, *head2;
int length1, length2; //分别记录两个循环链表的长度
printf("循环单链表的操作练习:
");
printf("创建两个单循环链表:
");
printf("第一个链表数据输入(请依次输入字符数据,#号结束):
");
head1 = CreateLinklist_End(&length1);
getchar(); //消除回车键为后面输入带来的影响
printf("第二个链表数据输入(请依次输入字符数据,‘#’号结束):
");
head2 = CreateLinklist_End(&length2);
printf("第一个链表的数据依次为:
");
ShowLinklist(head1);
printf("其节点数目为:%d
", length1);
printf("第二个链表的数据依次为:
");
ShowLinklist(head2);
printf("其节点数目为:%d
", length2);
printf("第一个链表和第二个链表的合并输出为:
");
head1 = Linklist_Connect(head1, length1, head2, length2);
ShowLinklist(head1);
return 1;
}
//尾插法创建循环单链表,参数l表示创建链表的长度
linklist *CreateLinklist_End(int *l)
{
linklist *head, *p, *e;
char ch;
*l = 0;
head = (linklist*)malloc(sizeof(linklist));
e = head;
ch = getchar();
while(ch != #)
{
*l = *l + 1;
p = (linklist*)malloc(sizeof(linklist));
p->data = ch;
e->next = p;
e = p;
ch = getchar();
}
e->next = head; //循环链表的尾结点指针域指向头节点
return head;
}
//单循环链表的合并
linklist *Linklist_Connect(linklist *h1, int l1, linklist *h2, int l2)
{
linklist *p1, *p2;
int l=1;
p1 = h1->next;
while(l<l1) //找到链表1的尾结点
{
l++;
p1 = p1->next;
}
p2 = h2->next;
l = 1;
while(l<l2) //找到链表2的尾结点
{
l++;
p2 = p2->next;
}
p1->next = p2->next->next; //核心操作:链表1的尾结点指向链表2辅助头节点的下个节点
p2->next = h1; //链表的尾结点指向链表1的辅助头节点
free(p2->next); //释放链表的辅助头节点
return h1;
}
//输出显示链表
void ShowLinklist(linklist *h)
{
linklist *p;
p = h->next;
while(p != h) //循环单链表的结束判断标志为不等于头节点
{
printf("%c ", p->data);
p = p->next;
}
printf("
");
}
