单链表实现两个有序链表序列的交集



已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。

输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用-1表示序列的结尾(-1不属于这个序列)。数字用空格间隔。

输出格式:
在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL。

输入样例:
1 2 5 -1
2 4 5 8 10 -1
输出样例:
2 5

分析:因为两个链表是非降序的序列,因此,我们可以将两个链表进行比较,小的就继续向后移动,直到两个表的元素相同时,就将相同的元素存放在新表中 



#include <iostream>
#define ok 1
#define error 0
#define overflow -2

using namespace std;
typedef int ElemType;
typedef int status;

//单链表的定义 
typedef struct LNode
{
	ElemType data;
	struct LNode *next;
}LNode , *LinkList;

//初始化
status InitList(LinkList &L)
{
	L = new LNode;
	L->next = NULL;
	return ok;
}
 
//尾插法创建单链表 
LinkList CreatList_R(LinkList &L)
{
	L = new LNode;
	L->next = NULL;
	LNode *r = L;
	while(1)
	{
		int e;
		cin >> e;
		if (e >= 0)                       //输入负数时就终止循环 
		{
			LNode *p = new LNode;
		    p->data = e;
		    p->next = NULL;
		    r->next = p;
		    r = p;
		}
		else
		    break;
	}
	return L;
}


//求交集 
void Same_List(LinkList La, LinkList Lb, LinkList Lc)
{
	LNode *pa, *pb, *pc;                   //生成三个LNode类型的指针pa, pb ,pc 
	pa = La->next;                         //pa指向La的首元结点 
	pb = Lb->next;                         //pb指向Lb的首元结点 
	
	//这里要区分和合并链表的算法
    //	Lc = La;    合并算法中是将La的头结点作为Lc的头结点,但在求交集算法中,加上这句,结果显示为NULL,
	//具体原因我也不是特别清楚,希望有知道的大佬可以留言告知一下           

	pc = Lc;                               //pc指向Lc的头结点 (pc用来存放交集部分) 
	pc->next = NULL;                       //pc的next域置空, 当前还没有存放数据 
	while (pa && pb)
	{
		if (pa->data < pb->data)           //两个链表当前结点的数据域进行比较,数据小的结点,就继续向后移动,指向下一个结点 
		{
			pa = pa->next;
		}
		else if (pa->data > pb->data)
			pb = pb->next;
		else
		{                                  //两个结点的数据域相同时 
			pc->next = pa;                 //就将pc结点的next域指向pa(或者pb)  
			pa = pa->next;                 //pa, pb结点指向下一结点 
			pb = pb->next;
			pc = pc->next;                 //pc指向下一结点 
		}
	}
}


//输出
int DispList(LinkList L)
{   //这里的判断条件很重要哦(PTA检测时,缺少判断条件,
    //可能会有格式或者编译错误,但在dev上面运行,只需要考虑结点p是否为空) 
    
	LNode *p = L->next;               //令结点P指向链表的首元结点 
    if(p == NULL)                     //如果p为空,说明首元结点就没有元素了,也就是整个链表都没有元素,是个只有头结点的空链表,就返回NULL 
        cout << "NULL" << endl;
    while(p != NULL)                  //如果p不为空,说明链表中有元素 
    {
       if(p->next != NULL)             //如果p的next域不为空,说明表中不止一个元素,就输出P所指向的结点的数据域 
        {
            cout << p->data << " ";   //输出p所指结点的数据域 
        }
      else
        	cout << p->data;          //如果首元结点的Next域为空,则说明表中只有一个元素,也就是只有首元结点的数据域有数据 
    p = p->next;                      //P指向下一个结点,直到p为空 
    }
	return 0;
} 


//主函数部分

int main()
{
	//初始化La, Lb, Lc 
	LinkList  La, Lb, Lc;    
 
    InitList(La);
    InitList(Lb);
    InitList(Lc);

	CreatList_R(La);
	CreatList_R(Lb);
	Same_List(La, Lb, Lc);
	
	DispList(Lc);               //输出交集Lc的元素 
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值