数据结构代码题总结-------Day06

本文介绍了如何通过算法解决链表数据结构的问题,包括:1) 不创建新链表的情况下求两个有序链表的交集并存放在A链表中;2) 判断两个整数序列是否为连续子序列;3) 检查循环双链表是否对称;4) 合并两个循环链表。每个问题都提供了详细的算法思路、代码实现及关键步骤解析。
摘要由CSDN通过智能技术生成

数据结构代码题总结

题目01

已知两个链表A和B分别表示两个集合,其元素递增有序排列,编制函数求A和B的交集,并存放在A链表中

题目分析:

  1. 求A和B的交集,与求A和B的公共元素不同
  2. 并存在在A链表中,-----代表着不可以再申请一个链表的存储空间
  3. 与不破坏A和B的结构节点不相同,这里不可以再申请一个新的链表空间。
  4. 存放在A链表中表示只可以在A链表上修改

算法思路图解

在这里插入图片描述
结合以上的算法图解,对其算法思路进行概述:

  1. 设置两个扫描指针p和q,进行对A和B链表的扫描进行操作,同时对其进行p和q所指向节点的数据进行比较
  2. 较小的数据进行后移,
  3. 若数据域相等时,这时进行标记节点标记删除节点,并对节点进行删除,释放空间
  4. 若遍历到表尾后,发现A或者B有剩余,因为已经有一个链表遍历完成,所以不会再存在相同的指针节点。直接释放空间就可以

这里强调下删除一个节点的步骤:
1、先使用一个标记节点u标记删除节点
2、将带删除节点指针后移
3、 free释放空间

下面是代码实现的核心代码:

	//核心代码
	while(p != null && q != null){
		//进行比较
		if(p->data < q->data){//不是交集的是直接释放删除
			u = p;
			p = p->next;
			free(u);
		}else if(p->data > q->data){//删除不必要的交集节点
			u = p;
			p = p->next;
			free(u);
		}else{//现在找到了相等的节点了,进行尾插法进行插入到A链表
			r->next = p;
			r = p;//保存A,释放B
			u= q;//考虑到资源的利用问题进行多余的节点删除
			q = q->next;
			free(u);
		}
	}
	//跳出循环说明A或者B出现一条链表遍历完毕,另一条未遍历完毕
	while(p != null){//A有剩余
		u = p;
		p =p->next;
		free(u);
	}
	while(q != null){//B有剩余
		u = q;
		q = q->next;
		free(u);
	}
	//尾插法必须设置尾指针
	r->next = null;
	free(B);//完全释放B节点

完整代码如下:

//找到链表的交集
Linklist Common_List(Linklist &A,Linklist &B){
	//初始化指针
	LNode * p = A->next;
	LNode * q = B->next;
	LNode * u;//作为标记指针
	A->next = null;//尾插法使用标准开端
	//设置一个尾插法的操作指针
	LNode * r = A;

	//核心代码
	while(p != null && q != null){
		//进行比较
		if(p->data < q->data){//不是交集的是直接释放删除
			u = p;
			p = p->next;
			free(u);
		}else if(p->data > q->data){//删除不必要的交集节点
			u = p;
			p = p->next;
			free(u);
		}else{//现在找到了相等的节点了,进行尾插法进行插入到A链表
			r->next = p;
			r = p;//保存A,释放B
			u= q;//考虑到资源的利用问题进行多余的节点删除
			q = q->next;
			free(u);
		}
	}
	//跳出循环说明A或者B出现一条链表遍历完毕,另一条未遍历完毕
	while(p != null){//A有剩余
		u = p;
		p =p->next;
		free(u);
	}
	while(q != null){//B有剩余
		u = q;
		q = q->next;
		free(u);
	}
	//尾插法必须设置尾指针
	r->next = null;
	free(B);//完全释放B节点
	return A;//返回A的操作节点
}

题目02

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

题目分析:
连续子序列-----代表要在A链表中找到一段连续的序与A进行对应。
关键在于如何在A中寻找B的连续子序列

答案是在我们无法首先得到最优化的解答时,暴力法无疑是能够最快拿到代码题分数的一个性价比极高的方法,相比于写不出来的代码题答案,在考试时使用暴力法写出来解答代码,虽然时间复杂度有时候会高点,但是基本的分数时很有保障的。

下面主要来讲解下暴力法解决连续子序列的问题,先看图
在这里插入图片描述
算法实现思路如下:

  1. 暴力法对p和q的数据域进行比较,
  2. 若数据域不相等,
  3. 那么p指针并在上次结束的位置进行向后移动
  4. q指针则是在起始位置进行移动
  5. 若相等,
  6. 那么p和q指针同时向后移动
  7. 判断结果处理:
  8. (1)若p在q之前先遍历结束,那么p中绝对不会存在B的连续子序列
  9. (2)若q先遍历完,说明找到了子序列,因此返回true

其实现的核心代码如下:

while(p != null && q != null){
		if(p->data != q->data){
			pre = pre->next;//找到之前pre节点的下一个节点
			p = pre;//设置p
			q = B->next;//q从头开始
		}else{
			p = p->next;
			q = q->next;//相等同时往后移
		}
	}
	//跳出循环
	if(q == null){//以q为主进行比较判断
		return true;
	}
	return false;

完整代码如下:

//查找连续组序列
boolean Find_SonLink(Linklist A,Linklist B){
	LNode * p = A->next;
	LNode * q = B->next;
	LNode * pre = p;//定义一个pre指针
	while(p != null && q != null){
		if(p->data != q->data){
			pre = pre->next;//找到之前pre节点的下一个节点
			p = pre;//设置p
			q = B->next;//q从头开始
		}else{
			p = p->next;
			q = q->next;//相等同时往后移
		}
	}
	//跳出循环
	if(q == null){//以q为主进行比较判断
		return true;
	}
	return false;
}

题目03

设计一个算法,判断带头结点的循环双链表是否对称

题目解析

什么是循环双链表对称??????
请先看下图
在这里插入图片描述
循环双链表对称的定义:

  1. 首尾的数据域在前进移动的过程中始终相等。
  2. 偶数节点的循环双链表,在p和q遍历的过程中,最终节点是(p==q)
  3. 奇数节点的结束条件是(q的next指向p)p和q相邻。

其实现代码如下:

while(p != q && q->next != p){
		  //偶数节点出循环  //奇数节点出循环
		  if(p->data == q->data){
		  	p = p->next;
		  	q = q->prior;
		  }else{
		  	return false;
		  }
	}
	return true;

完整代码如下:

//双链表结构体
typedef struct DLNode{
	ElemType data;
	struct DLNode * prior,*next;
}DLNode;

//是否对称
boolean Symmetry_link(DLinklist L){
	DLNode *p = L->next;
	DLNode *q =L->prior;
	while(p != q && q->next != p){
		  //偶数节点出循环  //奇数节点出循环
		  if(p->data == q->data){
		  	p = p->next;
		  	q = q->prior;
		  }else{
		  	return false;
		  }
	}
	return true;
}

题目04

两个循环链表h1和h2,编写一个函数将h2加入到h1之后,保持链表循环的形式

图解:
在这里插入图片描述
实现代码如下:

Linklist conn_link(Linklist &h1,Linklist &h2){
	LNode *p = h1;
	LNode * q = h2;
	//调整到表尾
	while(p!= h1){//作为链表尾部判断
		p = p->next;
	}
	while(q!= h2){//作为循环链表尾部判断
		q = q->next;
	}
	p->next = h2->next;//由于h2为头结点,在进行循环链表合并时,该节点不存储数据,因此为保证连续性,将h1链表的尾部的next指向h2的第一个数据节点。
	free(h2);//该步骤可释放也可不释放,理解算法思想即可
	q->next = h1;//进行尾部首部链接,保证为一个循环链表
	return h1;//返回循环链表
}

注:

个人代码问题或需要程序编写辅导服务等问题请加闲鱼【代码无bug】
或点击下面链接跳转闲鱼进行咨询

闲鱼链接

在这里插入图片描述

  • 14
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值