这道题我是直接将l1的尾链表指针指向l2的头链表指针,然后释放l2的头链表指针,然后将l2的尾链表指针指向l1的头链表指针(merge1函数)
但是答案的话是利用头插法将长度短的链表插入到长度长的链表(merge2函数)
两个我都实现了
代码
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//这一题进阶到循环单链表了
typedef struct node
{
int data;
struct node* next;
}Node;
typedef struct list
{
Node* head;
Node* tail;
int length;
}List;
void print_list(List L)
{
Node* p = L.head;
while(p->next != L.head)
{
printf("%d ", p->next->data);
p = p->next;
}
printf("\n");
printf("list length is %d\n",L.length);
}
void Init_list(List * L)
{
Node* first = (Node*)malloc(sizeof(Node));
assert(first != NULL);
first->data = 0;
first->next = L->head;
L->head = L->tail = first;
L->length = 0;
//尾插法建立链表
int size;
printf("please enter the list length: ");
scanf("%d",&size);
for(int i = 0;i < size; i++)
{
Node* new = (Node*)malloc(sizeof(Node));
int number;
scanf("%d",&number);
new -> data = number;
L->tail->next = new;
L->tail = new;
L->tail->next = L->head; //这里不要写的是L->tail->next = L->head->next 因为这是指针之间的赋值
L->length ++;
}
}
//这是直接改变头尾指针法
void merge(List* l1,List l2)
{
l1->tail->next = l2.head->next;
free(l2.head);
l2.tail->next = l1->head;
l1->length += l2.length;
}
//我看到答案是因为没有头尾指针,它是把短的那个链表插入到长的链表的前面
//为了要效率更快,所以找出长度短的那个插入
//这里为了练习,采用头插法的方式
void merge2(List* l1, List*l2)
{
Node* save, *q,*p;
q = l2->head->next;
p = l1->head->next;
if(l1->length > l2->length) //把l2插入到l1中
{
while(1)//因为是循环链表,所以不在是p!=NULL
{
save = q;
q = q->next;
save->next = l1->head->next;
l1->head->next = save;
if(q == l2->head ) //因为是循环链表,所以这一句不要忘了
break;
}
l1->length += l2->length;
print_list(*l1);
}
else
{
while(1)
{
save = p;
p = p->next;
save->next = q;
l2->head->next = save;
if(p == l1->head)
break;
}
l2->length += l1->length;
print_list(*l2);
}
}
int main(int argc, char const *argv[])
{
List l1,l2;
Init_list(&l1);
//print_list(l1);
Init_list(&l2);
//print_list(l2);
//merge2(&l1,&l2);
merge(&l1,l2);
print_list(l1);
return 0;
}
运行截图