【头歌实训:拆分单链表】

头歌实训:拆分单链表

文章目录

  • 任务描述
  • 相关知识
    • 单链表的基本概念
      • 单链表的头结点
      • 单链表的特点
      • 单链表插入一个结点
      • 单链表删除一个结点
      • 删除操作的语句如下:
    • 创建单链表
      • 头插法建立单链表
      • 尾插法建立单链表
    • 输出单链表
  • 编程要求
  • 测试说明
    • 输入格式
    • 输出格式
    • 样例输入
    • 样例输出
  • 源代码:

任务描述

本关任务:假设有一个带头结点的单链表L=(a1b1a2b2,…,an,bn)。设计一个算法将其拆分成两个带头结点的单链表L1和L2:L1=(a1,a2,…,an),L2=(bn,bn−1,…,b1)要求L1使用L的头结点。

在这里插入图片描述

相关知识

为了完成本关任务,你需要掌握:1.单链表的基本概念,2.如何创建、遍历单链表。

单链表的基本概念

单链表是线性表的链式存储结构实现。如下图所示:

在这里插入图片描述

单链表的头结点

为了操作方便,有时候会在单链表第一个元素结点的前面增加一个附加头结点,如下图所示:
在这里插入图片描述

单链表增加一个头结点的优点如下:

首结点的操作和表中其他结点的操作相一致,无需进行特殊处理;
无论链表是否为空,都有一个头结点,因此空表和非空表的处理也就统一了。
单链表结点类型定义
单链表中结点类型LinkNode的定义如下:

typedef struct LNode //定义单链表结点类型
{
ElemType data; //存储元素
struct LNode *next; //指向后继结点
} LinkNode;

单链表的特点

单链表的特点:当访问过一个结点 p 后,只能接着访问它的后继结点,而无法访问它的前驱结点。

单链表插入一个结点

插入操作:将值为x的新结点s插入到p结点之后。
特点:只需修改相关结点的指针域,不需要移动结点。
插入操作如下图所示:

在这里插入图片描述

单链表删除一个结点

删除操作:删除p结点之后的一个结点。
特点:只需修改相关结点的指针域,不需要移动结点。
删除操作如下图所示:

在这里插入图片描述

删除操作的语句如下:

p->next = p->next->next;

创建单链表

头插法建立单链表

从一个空表开始,创建一个头结点。
依次读取线性表中的元素,生成新结点s。
将新结点插入到当前链表的表头上,直到结束为止。
头插法建立单链表如下图所示:
在这里插入图片描述

建表语句如下:

void CreateListF(LinkNode *&L, ElemType a[], int n)
{
LinkNode *s;
L = (LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
L->next = NULL;
for (int i = 0; i < n; i++)
{
s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
s->data = a[i];
s->next = L->next; //将结点s插在原开始结点之前,头结点之后
L->next = s;
}
}

尾插法建立单链表

从一个空表开始,创建一个头结点。
依次读取线性表中的元素,生成新结点s
将新结点插入到当前链表的表尾上,直到结束为止。
尾插法建立单链表如下图所示:
在这里插入图片描述

建表语句如下:

void CreateListR(LinkNode *&L, ElemType a[], int n)
{
LinkNode *s, *r;
L = (LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
L->next = NULL;
r = L; //r始终指向终端结点,开始时指向头结点
for (int i = 0; i < n; i++)
{
s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
s->data = a[i];
r->next = s; //将结点s插入结点r之后
r = s;
}
r->next = NULL; //终端结点next域置为NULL
}

输出单链表

逐一扫描单链表L的每个数据结点,并显示各结点的data域值。

在这里插入图片描述

编程要求

根据提示,在右侧编辑器补充代码,完成函数void split(LinkNode *&L, LinkNode *&L1, LinkNode *&L2),将单链表L拆分为L1和L2。

测试说明

平台会对你编写的代码进行测试:

输入格式

输入包括两行。
第一行为单链表中元素个数n。
第二行为空格隔开的n个整数。

输出格式

输出包括四行。
第一行为单链表的元素。每个数据后一个空格。
第二行显示提示信息。
第三行显示单链表L1中的元素。每个数据后一个空格。
第四行显示单链表L2中的元素。每个数据后一个空格。

样例输入

6
1 2 3 4 5 6

样例输出

L: 1 2 3 4 5 6
L->L1,L2
L1: 1 3 5
L2: 6 4 2

开始你的任务吧,祝你成功!

源代码:

#include "linklist.h"

//将单链表L拆分成两个单链表L1和L2。
void split(LinkNode *&L, LinkNode *&L1, LinkNode *&L2)
{
	//请在下面编写代码
	/**********************Begin**********************/
	LinkNode *p = L->next, *p1 = L1, *s2;  //获得指针p指向L的首元节点,指针p1指向L1   
                                            //且L,L1,L2均带有头节点      
	int i = 1;          //i用来计数判断该插入L1还是L2
	while(p)       //while循环遍历p
    {
        if(i % 2 != 0)  //尾插法
        {
            p1->next = p;   
            p1 = p;     //P1向下一结点移动
        }
        else        //头插法
        {
            s2 = (LinkNode *)malloc(sizeof(LinkNode));
            s2->data = p->data;         //这里不能写成s2 = p,
            s2->next = L2->next;        //因为这里要让s2->next = L2->next,写成s2 = p,就会改变p的next,这就是地址的神奇之处。。。。。。
            L2->next = s2;
        }
        p = p->next;        //P向下一结点移动
        i++;
    }
    p1->next = NULL;        //p1尾部置为NULL
	/***********************End***********************/
}

int main()
{
	LinkNode *L, *L1, *L2;
	int n;
	scanf("%d", &n);
	ElemType a[n];
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	InitList(L);					//初始化单链表L
	InitList(L1);					//初始化单链表L1
	InitList(L2);					//初始化单链表L2
    //LinkNode *L3 = (LinkNode *)malloc(sizeof(LinkNode));
    //L3->next = NULL;
    //if (L3) printf("==========empty===========\n");   //这里会输出
	CreateListR(L, a, n);			//创建单链表L
	printf("L: "); DispList(L);		//输出单链表L
	printf("L->L1,L2\n");
	split(L, L1, L2);				//单链表L拆分为L1和L2
	printf("L1: "); DispList(L1);	//输出单链表L1
	printf("L2: "); DispList(L2);	//输出单链表L2
	DestroyList(L1);				//销毁单链表L1
	DestroyList(L2);				//销毁单链表L2
	return 0;
}
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/917651.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

渑池县中药材产业党委莅临河南广宇企业管理集团有限公司参观交流

11月14日&#xff0c;渑池县人大副主任、工商联主席杨航率县中药材产业党委代表团一行13人&#xff0c;莅临河南广宇集团参观交流。河南广宇集团总经理王峰、副总经理王培等领导热情接待并陪同参观、座谈。 代表团一行首先参观了集团旗下郑州美信中医院&#xff08;庚贤堂中医药…

零基础Java第十九期:认识String(一)

目录 一、String的重要性 二、String的常用方法 2.1. 字符串构造 2.2. String对象的比较 2.3. 字符串查找 2.4. 转化 2.4. 字符串替换 2.5. 字符串拆分 2.6. 字符串截取 一、String的重要性 在C语言中已经涉及到字符串了&#xff0c;但是在C语言中要表示字符串只能…

基于Lora通讯加STM32空气质量检测WIFI通讯

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着环境污染问题的日益严重&#xff0c;空气质量的监测与管理已经…

JMeter中添加请求头

在JMeter中添加请求头的步骤如下&#xff1a; 1.打开HTTP信息头管理器 &#xff1a; 首先&#xff0c;你需要进入JMeter的HTTP请求组件。这可以通过在HTTP请求测试元素上右键点击&#xff0c;然后选择“添加 > 配置元件 > HTTP信息头管理器”来完成。 2.添加新的请求头…

面试_ABtest原理简介

01 什么是ABtest ABtest来源于假设检验&#xff0c;现有两个随机均匀的有样本组A、B&#xff0c;对其中一个组A做出某种改动&#xff0c;实验结束后分析两组用户行为数据&#xff0c;通过显著性检验&#xff0c;判断这个改动对于我们所关注的核心指标是否有显著的影响&#xf…

PCB+SMT线上报价系统+PCB生产ERP系统自动化拼板模块升级

PCB生产ERP系统的智能拼版技术&#xff0c;是基于PCB前端报价系统获取到的用户或市场人员已录入系统的板子尺寸及set参数等&#xff0c;按照最优原则或利用率最大化原则自动进行计算并输出拼版样式图和板材利用率&#xff0c;提高工程人员效率&#xff0c;减少板材的浪费。覆铜…

Kubernetes 10 问,测测你对 k8s 的理解程度

Kubernetes 10 问 假设集群有 2 个 node 节点&#xff0c;其中一个有 pod&#xff0c;另一个则没有&#xff0c;那么新的 pod 会被调度到哪个节点上&#xff1f; 应用程序通过容器的形式运行&#xff0c;如果 OOM&#xff08;Out-of-Memory&#xff09;了&#xff0c;是容器重…

《操作系统 - 清华大学》3 -3:连续内存分配:内存碎片与分区的动态分配

文章目录 0. 概述1. 内存碎片问题2. 动态分配3. 首次适配算法4. 最优适配算法5. 最差适配算法 0. 概述 内存分配是操作系统管理过程中很重要的环节&#xff0c;首先需要考虑的是一块连续区域分配的过程&#xff0c;这个过程中会有很多问题&#xff0c;首先比较关注的一个问题是…

CICD持续集成与持续交付

一 CICD是什么 CI/CD 是指持续集成&#xff08;Continuous Integration&#xff09;和持续部署&#xff08;Continuous Deployment&#xff09;或持续交付&#xff08;Continuous Delivery&#xff09; 1.1 持续集成&#xff08;Continuous Integration&#xff09; 持续集成…

[前端面试]javascript

js数据类型 简单数据类型 null undefined string number boolean bigint 任意精度的大整数 symbol 创建唯一且不变的值&#xff0c;常用来表示对象属性的唯一标识 复杂数据类型 object&#xff0c;数组&#xff0c;函数,正则,日期等 区别 存储区别 简单数据类型因为其大小固定…

多线程-阻塞队列

目录 阻塞队列 消息队列 阻塞队列用于生产者消费者模型 概念 实现原理 生产者消费者主要优势 缺陷 阻塞队列的实现 1.写一个普通队列 2.加上线程安全和阻塞等待 3.解决代码中的问题 阻塞队列 阻塞队列&#xff0c;是带有线程安全功能的队列&#xff0c;拥有队列先进…

Uniapp 引入 Android aar 包 和 Android 离线打包

需求&#xff1a; 原生安卓 apk 要求嵌入到 uniapp 中&#xff0c;并通过 uniapp 前端调起 app 的相关组件。 下面手把手教你&#xff0c;从 apk 到 aar&#xff0c;以及打包冲突到如何运行&#xff0c;期间我所遇到的问题都会 一 一 进行说明&#xff0c;相关版本以我文章内为…

软间隔支持向量机

软间隔支持向量机 ​ 我们先直接给出软间隔支持向量机的形式&#xff1a; P min ⁡ ω , b , ζ 1 2 ∥ ω ∥ 2 2 − C ∑ i 1 m ζ i s . t . y i ( ω x i b ) ≥ 1 − ζ i , i 1 , 2 , 3.. m ζ i ≥ 0 , i 1 , 2 , 3.. m P \min_{\omega,b,\zeta} \frac{1}{2}\Ve…

html + css 自适应首页布局案例

文章目录 前言一、组成二、代码1. css 样式2. body 内容3.全部整体 三、效果 前言 一个自适应的html布局 一、组成 整体居中&#xff0c;宽度1200px&#xff0c;小屏幕宽度100% 二、代码 1. css 样式 代码如下&#xff08;示例&#xff09;&#xff1a; <style>* {…

深入List集合:ArrayList与LinkedList的底层逻辑与区别

目录 一、前言 二、基本概念 三、相同之处 四、不同之处 五、ArrayList 底层 六、LinkedList 底层 七、ArrayList 应用场景 八、LinkedList 应用场景 九、ArrayList和LinkedList高级话题 十、总结 一、前言 在Java集合的广阔舞台上&#xff0c;ArrayList与LinkedLis…

Vue3中实现插槽使用

目录 一、前言 二、插槽类型 三、示例 四、插槽的分类实现 1. 基本插槽 2. 命名插槽 3. 默认插槽内容 4. 作用域插槽&#xff08;Scoped Slots&#xff09; 5. 多插槽与具名插槽组合 一、前言 在 Vue 3 中&#xff0c;插槽&#xff08;Slot&#xff09;用于实现组件的内…

海思3403对RTSP进行目标检测

1.概述 主要功能是调过live555 testRTSPClient 简单封装的rtsp客户端库&#xff0c;拉取RTSP流&#xff0c;然后调过3403的VDEC模块进行解码&#xff0c;送个NPU进行目标检测&#xff0c;输出到hdmi&#xff0c;这样保证了开发没有sensor的时候可以识别其它摄像头的视频流&…

【Java知识】Java性能测试工具JMeter

一文带你了解什么是JMeter 概述JMeter的主要功能&#xff1a;JMeter的工作原理&#xff1a;JMeter的应用场景&#xff1a;JMeter的组件介绍&#xff1a; 实践说明JMeter实践基本步骤&#xff1a;JMeter实践关键点&#xff1a; JMeter支持哪些参数化技术&#xff1f;常见插件及其…

Github客户端工具github-desktop使用教程

文章目录 1.客户端工具的介绍2.客户端工具使用感受3.仓库的创建4.初步尝试5.本地文件和仓库路径5.1原理说明5.2修改文件5.3版本号的说明5.4结合码云解释5.5版本号的查找 6.分支管理6.1分支的引入6.2分支合并6.3创建测试仓库6.4创建测试分支6.5合并分支6.6合并效果查看6.7分支冲…

Flutter中的Material Theme完全指南:从入门到实战

Flutter作为一款热门的跨平台开发框架&#xff0c;其UI组件库Material Design深受开发者喜爱。本文将深入探讨Flutter Material Theme的使用&#xff0c;包括如何借助Material Theme Builder创建符合产品需求的主题风格。通过多个场景和代码实例&#xff0c;让你轻松掌握这一工…