已知两个链表L1和L2分别表示两个集合,其中元素递增排列。请设计一个算法,用于求出L1与L2的交集,并存放在L1链表中

已知两个链表L1和L2分别表示两个集合,其中元素递增排列。请设计一个算法,用于求出L1与L2的交集,并存放在L1链表中。

代码思路:
我们创建一个辅助链表L3,用于存储L1和L2链表的交集,用s遍历L3各个元素

用p和q分别遍历链表L1和L2,因为是两个链表都是递增的,所以每次比较p和q结点那个元素更小,更小的往后移。如果p和q指向结点大小一样,则把它们记录到s中。

过程示意图如下:
已知两个链表L1和L2分别表示两个集合,其中元素递增排列。请设计一个算法,用于求出L1与L2的交集,并存放在L1链表中_第1张图片
已知两个链表L1和L2分别表示两个集合,其中元素递增排列。请设计一个算法,用于求出L1与L2的交集,并存放在L1链表中_第2张图片
已知两个链表L1和L2分别表示两个集合,其中元素递增排列。请设计一个算法,用于求出L1与L2的交集,并存放在L1链表中_第3张图片
已知两个链表L1和L2分别表示两个集合,其中元素递增排列。请设计一个算法,用于求出L1与L2的交集,并存放在L1链表中_第4张图片

已知两个链表L1和L2分别表示两个集合,其中元素递增排列。请设计一个算法,用于求出L1与L2的交集,并存放在L1链表中_第5张图片
已知两个链表L1和L2分别表示两个集合,其中元素递增排列。请设计一个算法,用于求出L1与L2的交集,并存放在L1链表中_第6张图片

最后当某个链表遍历结束,循环也可以结束了,因为一个链表后面没东西了,咋能和另一个链表有交集呢?

然后题目要求把交集放在L1中,所以把L3的复制进去即可。

//两个递增链表,求交集
void JiaoJi(LinkList* L1, LinkList* L2) {
	LNode* p = (*L1)->next;//用p遍历L1
	LNode* q = (*L2)->next;//用q遍历L2
	
	LinkList L3 = (LNode*)malloc(sizeof(LNode));//辅助链表,用于存放公共元素
	LNode* s = (LNode*)malloc(sizeof(LNode));//用s遍历L3
	L3->next = s;

	LNode* pre = L3;//记录s前一个位置
	while (p&&q) {

		if (p->next == NULL || q->next == NULL) {//下一轮退出循环,记录当前s位置
			pre->next=NULL;
		}

		if (p->data == q->data) {
			LNode* tmp = (LNode*)malloc(sizeof(LNode));
			tmp->next = NULL;
			s->data = p->data;
			s->next =tmp;
			s = s->next;
			p = p->next;
			q = q->next;

			pre = pre->next;
		}
		else if (p->data > q->data) {
			q = q->next;
		}
		else {
			p = p->next;
		}
	}
	
	

	s = L3->next;//s复位
	p = (*L1)->next;//p复位
	LNode* tmp = (LNode*)malloc(sizeof(LNode));
	while (s!=NULL) {//因为L3是L1和L2的交集,所以L3的长度是一定小于等于L1的,这里判断条件给一个s即可
		if (s->next == NULL) {//出循环的前一个,记录一下此时的p位置
			tmp = p;
		}
		p->data = s->data;
		p = p->next;
		s = s->next;
	}
	tmp->next = NULL;//把L1后面的非交集部分断掉
}
int main() {
	LinkList L1;
	LinkList L2;
	InitList2(&L1);//初始化一个1 2 3 4 5 6 7 8 9 10的带头结点链表L1
	InitList3(&L2);//初始化一个4 5 6 7 8 9的带头结点链表L2

	printf("初始L1为:");
	print2(L1);
	
	printf("\n");
	
	printf("初始L2为:");
	print2(L2);
	
	printf("\n");
	
	JiaoJi(&L1, &L2);
	printf("L1和L2交集为:");
	print2(L1);

	return 0;
}

已知两个链表L1和L2分别表示两个集合,其中元素递增排列。请设计一个算法,用于求出L1与L2的交集,并存放在L1链表中_第7张图片
注:初始化带头单链表和打印函数

#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
//单链表定义
//链表结点
int A[10] = { 1,2,3,4,5,6,7,8,9,10 };
int B[6] = { 4,7,8,9,11,13 };//4,7,8,9,11,13
typedef struct {//定义单链表结点类型
	int data;//数据域
	struct LNode *next;//指针域
}LNode, *LinkList;


//带头结点初始化-尾插法
void InitList2(LinkList* L) {
	(*L) = (LNode*)malloc(sizeof(LNode));
	(*L)->next = NULL;
	LNode* rear = (*L);//标记表尾
	int i = 0;
	for (i = 0;i < 10;i++) {
		LNode* p = (LNode*)malloc(sizeof(LNode));//创建一个新结点
		p->data = A[i];//新结点赋值
		rear->next = p;//接到L上
		rear = p;//标记表尾
	}
	rear->next = NULL;
}

//带头结点初始化-尾插法
void InitList3(LinkList* L) {
	(*L) = (LNode*)malloc(sizeof(LNode));
	(*L)->next = NULL;
	LNode* rear = (*L);//标记表尾
	int i = 0;
	for (i = 0;i < 6;i++) {
		LNode* p = (LNode*)malloc(sizeof(LNode));//创建一个新结点
		p->data = B[i];//新结点赋值
		rear->next = p;//接到L上
		rear = p;//标记表尾
	}
	rear->next = NULL;
}

void print2(LinkList L) {//打印带头结点的链表
	LNode* i = L->next;//用i指针遍历整个链表
	while (i != NULL) {
		printf("%d ", i->data);
		i = i->next;
	}
}

你可能感兴趣的:(数据结构代码汇总,链表,算法,数据结构,求链表交集,相同结点)