有序表的合并去重

问题描述

已知两个有序线性表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);
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值