问题描述
已知两个有序线性表L1和L2,每个线性表中数据元素的值为单调增的正整数(<100个),各线性表内部无重复元素。把L2中的元素合并到L1中,要求L1中数据元素的值仍为单调递增,且无重复元素。
问题输入
第一行输入两个正整数a,b,分别表示第一个线性表L1和第二个线性表L2的长度;第2行依次输入L1中单调增的a个正整数;第3行依次输入L2中单调增的b个正整数。正整数均小于10000。
问题输出
共有1行,最终合并并去重后的结果,每个数字之间有一个空格。
输入样例
6 7
1 2 5 6 10 13
1 3 5 8 19 22 31
输出样例
1 2 3 5 6 8 10 13 19 22 31
提示
创建两个链表,利用指针定位链表元素位置,将光标指向的元素进行比较,较小的连接在新链表表尾,同时该光标指针后移一位,若两元素相等,则将其中一个结点连接在新表表尾,两光标同时后移一位,得到合并完成的新表
C语言代码实现
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{//有序线性表元素结点
int data;
struct Node* next;
}Node;
Node* CreatList(int); //创建一个链表
Node* Combine(Node*,Node*); //合并链表
void Traverse(Node*); //遍历链表
int main()
{
int n,m;
printf("请输入两个有序线性表的长度:");
scanf("%d %d",&n,&m);
Node* pHead1 = CreatList(n);
Node* pHead2 = CreatList(m);
Node* pHead3 = Combine(pHead1,pHead2);
Traverse(pHead3);
return 0;
}
Node* CreatList(int n)
{//创建一个链表,并返回头指针
Node* pHead = (Node*)malloc(sizeof(Node));
if(pHead == NULL)
exit(-1);
Node* pTail = pHead;
pHead->next = NULL;
printf("请输入有序线性表:");
for(int i=0;i<n;i++)
{
Node* pNew = (Node*)malloc(sizeof(Node)); //为新结点开辟存储空间
if(pNew == NULL)
exit(-1);
scanf("%d",&pNew->data); //输入元素值,并赋值给新结点data变量
pNew->next = NULL; //初始化新结点指针域
pTail->next = pNew; //尾结点指针域指向新结点
pTail = pNew; //更新尾结点
}
return pHead;
}
Node* Combine(Node* pHead1,Node* pHead2)
{//链表合并去重
Node* p1 = pHead1->next; //链表1的指针光标,定位当前需要比较的结点
Node* p2 = pHead2->next;
Node* pHead3 =(Node*)malloc(sizeof(Node)); //新链表头指针
if(pHead3 == NULL)
exit(-1);
Node* p3 = pHead3;
p3->next = NULL;
while(p1!=NULL && p2!=NULL)
{//循环比较光标指向结点,合并成一个新链表
if(p1->data > p2->data)
{
p3->next = p2;
p3 = p2;
p2 = p2->next;
}
else if(p1->data < p2->data)
{
p3->next = p1;
p3 = p1;
p1 = p1->next;
}
else
{
p3->next = p1;
p3 = p1;
p1 = p1->next;
Node* q = p2;
p2 = p2->next;
free(q);
q = NULL;
}
}
p3->next = p1==NULL ? p2 : p1;
return pHead3;
}
void Traverse(Node* pHead)
{
Node* p = pHead;
while(p->next!=NULL)
{
p = p->next;
printf("%d ",p->data);
}
}