问题描述:设list1与list2分别为两个带有头节点的有序循环链表(所谓有序是指链表节点按照数据域值的大小链接,本题中节点按照数据域的值从小到大排列),plist1和plist2分别为指向两个链表的头指针。请写出将这两个链表合并为一个带头结点的有序循环链表的算法并且编程实现。
#include<stdio.h>
#include<stdlib.h>
typedef struct tagLNode{
int data;
struct tagLNode *next;
}LNode,*LinkList;//定义struct数据类型
void CreateList(LinkList *L)
{
LinkList q,s;
*L=(LinkList)malloc(sizeof(LNode));
(*L)->next=*L;//(*L)->next指向自身,实现循环链表。
for(;;){
s=(LinkList)malloc(sizeof(LNode));
scanf("%d",&s->data);
if(s->data==0)break;//当输入数据0时结束此循环
else{
q=*L;
while((q->next!=*L)&&(s->data>q->next->data))q=q->next;//比较当前输入的数据与链表中的数据,找到比它大的插入到其前面。
s->next=q->next;
q->next=s;
}
}
}//创建链表函数
void MergeList(LinkList La,LinkList Lb,LinkList *Lc)
{
*Lc=(LinkList)malloc(sizeof(LNode));
(*Lc)->next=NULL;
LinkList pa=La->next,pb=Lb->next,pc=*Lc;
while((pa!=La)&&(pb!=Lb)){//当pa与pb都没有等于头结点时,进行以下操作。
if(pa->data<=pb->data){//比较la与lb中的数据,按非递减序插入到lc后面。
pc->next=pa;
pc=pa;
pa=pa->next;
}//当pa->data较小时,把其数据接入链表*Lc中。
else{
pc->next=pb;
pc=pb;
pb=pb->next;
}//当pb->data较小时,把其数据接入链表*Lc中。
}
if(pa!=La){// 当Lb链表插入完后,La还有剩余数据,则将这些数据接在lc的后面。
while(pa!=La){
pc->next=pa;
pc=pa;
pa=pa->next;
}
}
else{// 当La链表插入完后,Lb还有剩余数据,则将这些数据接在lc的后面。
while(pb!=Lb){
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
pc->next=*Lc;
}//链表连接函数
void PrintList(LinkList *head)
{
LNode *p;
p=*head;
while(p->next!=*head){//因为要输出的链表都是循环链表,因此输出控制条件应该是当指针不是指向头结点时。
printf("%d ",p->next->data);
p=p->next;
}
printf("\n");
}//链表输出函数
int main()
{
LinkList list1,list2,list3;
printf("输入第一个链表(以0结束):\n");
CreateList(&list1);
PrintList(&list1);
printf("输入第二个链表(以0结束):\n");
CreateList(&list2);
PrintList(&list2);
printf("数据以非递减排列:\n");
MergeList(list1,list2,&list3);
PrintList(&list3);
return 0;
}