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

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

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

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

输出样例:
2 5




idea:看到这道题第一想法就是创建两个带头结点的链表,用尾插法实现,然后再用指针依次遍历。





步骤1:建立节点;
步骤2:尾插法构建两个链表
步骤3:比较两个链表的数据,既然是有序链表,那么就可以比较数据。


最初的错误idea(第二个想法有问题)

  1. 如果第一个链表一个节点数据小于第二个链表的一个节点数据,那么就把第一个链表的指针指向下一个节点,第二个链表 的指针不移动。
  2. 如果第一个链表一个节点数据等于第二个链表的一个节点数据,那么就把第一个链表的指针指向下一个节点,第二个链表 的指针不移动。
  3. 如果第一个链表一个节点数据大于第二个链表的一个节点数据,那么第一个链表的指针不移动,第二个链表的指针指向下一个节点。

过了许多天重新写的…只加了一个构建链表函数的18分代码:
(比起上次的多了一个判断交集是否为空,就多了两分)

#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
	int data;
	struct node *next;
}node;
struct node *createList();
int main()
{
	//尾插法创建链表 
	node *L1 = createList();
	node *L2 = createList();
	int cnt = 0,num = 0;//num统计交集个数 
	node *p1 = L1;
	node *p2 = L2; 
	while(p1!=NULL&&p2!=NULL)
	{
		if(p1->data<p2->data)
		{
			p1 = p1->next;
		}
		else if(p1->data == p2->data)
		{//cnt为了规范输出 
			num++;		
			if(cnt == 0) 
			{
				cnt = 1;
				printf("%d",p1->data);
			}
			else
			{
				printf(" %d",p1->data);
			}
			p1 = p1->next;
		}
		else
		{
			p2 = p2->next;
		}
	}
	if(num==0)
		printf("NULL");	
	return 0;
}
struct node *createList()
{
	node *head = NULL;
	head = (node*)malloc(sizeof(node));
	head->next = NULL;
	node *p = head;
	int x;
	scanf("%d",&x);
	while(x!= -1)
	{
		node *q =NULL;
		q = (node*)malloc(sizeof(node));
		q->data = x;
		p->next = q;
		p = q;
		q->next = NULL;
		//q->next = NULL是必要的,否则最后会使q指针
		//指向一个未知空间,导致程序错误 
		scanf("%d",&x);
	}
	return head->next;
}

想了许久,不知道为什么大规模数据测试点是错的,然后想了一个测试用例

1 2 2 2 2 -1
1 2 2 2 -1


结果输出的是1 2 2 2 2 ,很惊奇,于是发现idea的第二点有问题,应该这样改:

1.如果第一个链表一个节点数据小于第二个链表的一个节点数据,那么就把第一个链表的指针指向下一个节点,第二个链表 的指针不移动。
2. 如果第一个链表一个节点数据等于第二个链表的一个节点数据,那么就把第一个链表的指针指向下一个节点,

第二个链表 的指针也指向下一个节点


3. 如果第一个链表一个节点数据大于第二个链表的一个节点数据,那么第一个链表的指针不移动,第二个链表的指针指向下一个节点。

于是就好改了
20分代码:

#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
	int data;
	struct node *next;
}node;
struct node *createList();
int main()
{
	//尾插法创建链表 
	node *L1 = createList();
	node *L2 = createList();
	int cnt = 0,num = 0;//num统计交集个数 
	node *p1 = L1;
	node *p2 = L2; 
	while(p1!=NULL&&p2!=NULL)
	{
		if(p1->data<p2->data)
		{
			p1 = p1->next;
		}
		else if(p1->data == p2->data)
		{//cnt为了规范输出 
			num++;		
			if(cnt == 0) 
			{
				cnt = 1;
				printf("%d",p1->data);
			}
			else
			{
				printf(" %d",p1->data);
			}
			p1 = p1->next;
			p2 = p2->next;
		}
		else
		{
			p2 = p2->next;
		}
	}
	if(num==0)
		printf("NULL");	
	return 0;
}
struct node *createList()
{
	node *head = NULL;
	head = (node*)malloc(sizeof(node));
	head->next = NULL;
	node *p = head;
	int x;
	scanf("%d",&x);
	while(x!= -1)
	{
		node *q =NULL;
		q = (node*)malloc(sizeof(node));
		q->data = x;
		p->next = q;
		p = q;
		q->next = NULL;
		//q->next = NULL是必要的,否则最后会使q指针
		//指向一个未知空间,导致程序错误 
		scanf("%d",&x);
	}
	return head->next;
}

继续努力。