王道数据结构2022-线性表的链式表示-综合题(p41)-16两个整数序列A=a1,a2,a3,...,am和B=b1,b2,b3,...,bn已经存入两个单链表中,设计一个算法,判断序列B是否是序列

两个整数序列A=a1,a2,a3,…,am和B=b1,b2,b3,…,bn已经存入两个单链表中,设计一个算法,判断序列B是否是序列A的连续子序列

#include<stdio.h>
#include<stdlib.h>

typedef struct LNode { //定义单链表结点类型
	int data;//数据域
	struct LNode *next;//指针域
} LNode, *LinkList;

/*两个整数序列A=a1,a2,a3,...,am和B=b1,b2,b3,...,bn已经存入两个单链表中,
设计一个算法,判断序列B是否是序列A的连续子序列*/

/*算法思想:
因为两个整数序列已存入两个链表中,操作从两个链表的第一个结点开始,
若对应数据相等,则后移指针;若对应数据不等,则A链表从上次开始比较结点的后继开始,
B链表仍从第一个结点开始比较,直到B链表到B尾表示匹配成功.
A链表到尾,而B链没到尾表示失败.
操作中应记住A链表每次的开始结点,以便下次匹配时好从其后继开始*/
void Pattern(LinkList A,LinkList B) {
	//A和B分别是数据域为整数的单链表,本算法判断B是否是A的子序列
	LNode *p = A->next,*pre = p, *q = B->next;
	//p,q为工作指针,pre记住每趟比较中A链表的开始结点
	while(p&&q) {
		if(p->data==q->data) { //结点值相同
			p=p->next;
			q=q->next;
		} else {
			pre=pre->next;
			p=pre;//A链表从新的开始比较结点
			q=B->next;//q从B链表第一个结点开始
		}
	}
	if(q==NULL) //B到表尾
		printf("\n序列B是序列A的连续子序列") ;
	else//A到表尾
		printf("\n序列B不是序列A的连续子序列") ;

}


//求表长
int Length(LinkList L) {
	int count=0;
	LNode *p=L->next;
	while(p!=NULL) {
		count++;
		p=p->next;
	}
	return count;
}

/*算法思想:
判断序列B是否是序列A的连续子序列,显然,m<n
可依次从A,B第一个结点开始遍历,如果序列B
从第一个结点开始至最后一个结点都与A有对应的结点
则序列B是序列A的连续子序列,反之,不是*/
void SubSequence(LinkList A,LinkList B) {
	LNode *pa=A->next ,*pb=B->next;
	int count=0;//记录序列B的第一个结点对应的出现
	if(Length(A)<Length(B)) {
		printf("不是连续子序列,因为序列A长小于B长");
		return;
	}
	while(pa!=NULL&&pb!=NULL) {
		if(pa->data == pb->data) {
			count=1;
			pa=pa->next;
			pb=pb->next;
		} else {
			if(count == 1) {
				printf("\nB不是A的连续子序列");
				return;
			} else
				pa=pa->next;
		}
	}
	printf("\nB是A的连续子序列") ;
}

//带头结点尾插法建立单链表
LinkList List_TailInsert(LinkList &L) { //正向建立单链表
	int x;
	L=(LinkList)malloc(sizeof(LNode));
	L->data=999999;
	LNode *s, *r=L;//r为表尾指针
	printf("请输入数值\n");
	scanf("%d",&x);
	while(x!=9999) { //输入 9999表示结束
		s=(LNode *)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r=s;//r指向新的表尾结点
		scanf("%d",&x);
	}
	r->next = NULL;//尾结点指针置空
	return L;
}
//打印链表
void print(LinkList L) {
	printf("\n");
	if(L->next==NULL)
		printf("该链表为空");
	LNode *p= L->next;
	while(p!=NULL) {
		printf("%d ",p->data);
		p=p->next;
	}
}




int main() {
	LinkList A,B;
	int x;
	List_TailInsert(A);
	List_TailInsert(B);
	print(A);
	print(B);
	Pattern(A,B);
//	SubSequence(A,B);低级,且不准确
	return 0;
}

运行结果

在这里插入图片描述

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
线性是一种常见的数据结构,它表示具有相同数据类型的一组元素的有序序列线性的元素之间存在一种顺序关系,每个元素都有一个前驱和一个后继(除了第一个元素没有前驱,最后一个元素没有后继)。线性可以用顺序存储结构或链存储结构实现。 在顺序存储结构线性的元素按照顺序存储在连续的内存空间,可以通过元素的下标来访问和操作元素。插入或删除元素时,需要移动其他元素,因此操作的时间复杂度较高。 链存储结构线性的每个元素都包含一个数据域和一个指针域,指针指向下一个元素。通过指针的链接,元素可以按照任意顺序存储在内存,插入和删除操作只需要改变指针的指向,因此时间复杂度较低。 线性常见的操作包括插入、删除、查找、获取长度等。其插入和删除操作需要注意保持线性的顺序关系。 常见的线性有数组、链表、栈和队列。数组是最简线性,通过下标可以直接访问元素;链表是动态存储结构,插入和删除操作方便,但访问元素需要遍历链表;栈是一种特殊的线性,只允许在的一端进行插入和删除操作;队列也是一种特殊的线性,只允许在的一端进行插入操作,在另一端进行删除操作。这些数据结构在实际应用都有各自的应用场景和优缺点。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值