【PTA】两个有序链表合并(新表不含重复元素) (20 分)

在这里插入图片描述
在这里插入图片描述
有了第一次处理死循环的经验,这一次轻松多了~
就是要注意出现死循环的条件,要记得给出所有情况的方法,不然程序就会卡住不动

两个表会出现:
一个空一个非空,两个非空,两个空的情况。Union的时候要判断全了~

AC代码:(很长,惭愧惹)

#include<iostream>
using namespace std;

typedef struct LNode
{
	int data;
	struct LNode *next;
}LNode,*LinkList;

void createList(LinkList &L)
{
	int n;
	L=new LNode;
	L->next=NULL;
	LinkList p,r=L;//r是扫描指针 
	while(cin>>n)
	{
		if(n==-1) break;
		p=new LNode;
		p->data=n;
		p->next=NULL;
		r->next=p;
		r=p;		
	}
}

void Union(LinkList s1,LinkList s2,LinkList &s3)
{
	s3=new LNode;
	s3->next=NULL;
	LinkList r=s3,p1=s1->next,p2=s2->next;
	
	//先比较第一个:两个都非空表的情况
	if(p1&&p2) 
	{
		if(p1->data==p2->data)
		{
			LinkList p=new LNode;
			p->data=p2->data;
			p->next=NULL;
			r->next=p;
			r=p;
			p2=p2->next;
			p1=p1->next;
		}
		else if(p1->data<p2->data)				
		{
			LinkList p=new LNode;
			p->data=p1->data;
			p->next=NULL;
			r->next=p;
			r=p;
			p1=p1->next;			
		}		
		else if(p1->data>p2->data)
		{
			LinkList p=new LNode;
			p->data=p2->data;
			p->next=NULL;
			r->next=p;
			r=p;
			p2=p2->next;	
		}
	}
	
	//有至少一个空表 
	else
	{
		//先放第一个
		if(p1)
		{
			LinkList p=new LNode;
			p->data=p1->data;
			p->next=NULL;
			r->next=p;
			r=p;
			p1=p1->next;
		}
		
		else if(p2)
		{
			LinkList p=new LNode;
			p->data=p2->data;
			p->next=NULL;
			r->next=p;
			r=p;
			p2=p2->next;
		}
		
		//再往后放
		while(p1)
		{
			if(r->data<p1->data)
			{
				LinkList p=new LNode;
				p->data=p1->data;
				p->next=NULL;
				r->next=p;
				r=p;				
			}
			p1=p1->next;
		} 
		
		while(p2)
		{
			if(r->data<p2->data)
			{
				LinkList p=new LNode;
				p->data=p2->data;
				p->next=NULL;
				r->next=p;
				r=p;				
			}
			p2=p2->next;
		} 
	}
	
	//两个表都存在的情况 
	while(p1&&p2)
	{
		
		//要先判断是否相同 
		if(p1->data==p2->data&&(r->data<p2->data))
		{			
			LinkList p=new LNode;
			p->data=p2->data;
			p->next=NULL;
			r->next=p;
			r=p;
			p2=p2->next;
			p1=p1->next;							
			
		}
		
		else if(p1->data<p2->data&&(r->data<p1->data))				
		{
			LinkList p=new LNode;
			p->data=p1->data;
			p->next=NULL;
			r->next=p;
			r=p;
			p1=p1->next;
						
		}
		
		else if(p1->data>p2->data&&(r->data<p2->data))
		{
			LinkList p=new LNode;
			p->data=p2->data;
			p->next=NULL;
			r->next=p;
			r=p;
			p2=p2->next;	
		}
		
		//注意,这里要设置都不满足的操作,不然又会死循环
		//这里是r->data==p->data的情况
		else
		{
			if(r->data==p1->data) p1=p1->next;
			if(r->data==p2->data) p2=p2->next;
		} 
	}
	
	//有一遍已经循环完毕 
	while(p1)
	{
		if(p1->data>r->data)
		{
			LinkList p=new LNode;
			p->data=p1->data;
			p->next=NULL;
			r->next=p;
			r=p;
			p1=p1->next;
		}
		else
		{
			p1=p1->next;
		}
	}
	
	while(p2)
	{
		if(p2->data>r->data)
		{
			LinkList p=new LNode;
			p->data=p2->data;
			p->next=NULL;
			r->next=p;
			r=p;
			p2=p2->next;
		}
		else p2=p2->next;		
	}
	
	
}
int main()
{
	LinkList s1,s2,s3;
	createList(s1);
	createList(s2);
	Union(s1,s2,s3);
	
	if(s3->next==NULL)
	{
		cout<<"NULL";
		return 0;
	}
	
	LinkList p=s3->next;
	int temp=0;
	while(p)
	{
		if(temp) cout<<" ";
		cout<<p->data;
		p=p->next;
		temp++;
	}
	
	return 0;
}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

karshey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值