【数据结构每日一题】链表——单链表重排

news2024/11/25 4:32:39

[数据结构习题]链表——单链表重排



👉知识点导航💎:【数据结构】线性表——顺序存储

👉知识点导航💎:【数据结构】线性表——链式存储

👉[王道数据结构]习题导航💎: p a g e 41.25 page41.25 page41.25

本节为链表相关操作的习题

在这里插入图片描述



☀️题目描述:

在这里插入图片描述



🎇思路:单链表逆置

🔱思路分析:

题目解析:我们先分析题目,对于初始单链表 L ( a 1 , a 2 , a 3 , . . . , a n ) L(a1,a2,a3,...,an) L(a1,a2,a3,...,an)和目标单链表 L ′ ( a 1 , a n , a 2 , a n − 1 , . . . ) L'(a1,an,a2,a_{n-1},...) L(a1,an,a2,an1,...),不难发现 L ′ L' L是通过 L L L摘取第 1 1 1和第 n n n个元素,再摘取第 2 2 2和第 n − 1 n-1 n1元素,…,最后摘取第 k k k和第 n − k + 1 n-k+1 nk+1个元素(奇数个结点时也可能没有),最后拼接而成的单链表


即首尾对应依次取出,可以分为前后两段,一个指针不断向后,一个指针不断向前?
在这里插入图片描述

这就是这道题的关键问题:单链表只能从前向后找,而不能从后向前,且题目要求空间复杂度为 O ( 1 ) O(1) O(1),也就是不能构造辅助数组存储,那么应该怎么做呢?


既然不能从后向前,那我们就想办法让前段和后段在遍历时保持一致,可以通过对单链表后段进行逆置处理


step:

1. 找中间结点

要想逆置后段链表,则必须先找到前段和后段的分界点,所以我们第一步是找到中间结点

对于奇数个结点 ( 2 n + 1 ) (2n+1) (2n+1)的链表:我们需要找到第 n + 1 n+1 n+1个结点;对于偶数个结点 2 n 2n 2n的链表:我们需要找到第 n n n个结点


算法思路:

p移动1步,q移动2步(最后一步时,若为奇数个结点则移动1步),当q指向尾结点时,p正好指向中间结点:

  1. 设置两个指针 p , q p,q p,q,开始时,同时指向头结点,开始向后移动;
  2. 当q指向的下一个结点不为 N U L L NULL NULL时, p , q p,q p,q同时移动1步;
  3. 此时,继续判断q指向的下一个结点是否为 N U L L NULL NULL,若不为空,则再向后移动1步;若为空,则结束,此时的p即指向中间结点

①偶数个结点:
在这里插入图片描述

②奇数个结点:

在这里插入图片描述

key:q每走一步都要进行一次判空操作


代码实现:

	LNode* p = L, * q = L; //p,q初始都指向头结点
	while (q->next != NULL) {
		p = p->next;
		q = q->next;
		if (q->next != NULL) //q每走一步都要先判断
			q = q->next;
	}


2. 后段链表逆置

在找到中间结点后,我们就可以对结点后面的链表进行逆置处理啦~

对于单链表的逆置,其无法像数组一样随机访问,直接交换首尾的数据,所以我们的思路是:“让单链表的箭头反向”,再将中间结点连接至最后一个结点


算法思路:

  1. 先让指针 q q q指向后段的首结点,再将指向中间点的指针 p p p 指向 N U L L NULL NULL


    这里为什么要让指针 p p p 指向NULL呢?其实目的就是让前段和后段暂时断开

    图解:

    在这里插入图片描述


  1. q q q 不指向 N U L L NULL NULL时(即后段还有剩余结点未处理时),我们先记录 q q q 的下一个结点指针 r r r再让当前 q q q n e x t next next指向 p p p的下一个结点, q q q n e x t next next结点指向 p p p,最后移动 q q q r r r位置;


    这里我们要思考:

    1. q->next=p->next;p->next=q的含义是什么?
    p作为中间结点的指针,若要链表逆序,则最后p的next指针一定是要指向链表的尾结点的,所以,我们每扫到一个后段结点,都把他当作尾结点来看,则 q的next指针要指向上一轮 p的next指向的结点,这样就完成了箭头反向(因为上一轮p的next指向前一个结点),再让 p的next指向当前结点 q,即连接了表尾,实现了部分逆序

    2. 为什么要单独记录 q q q n e x t next next指针 r r r
    因为当q->next发生改变后,q之后的后段结点与当前逆序的部分断开,若不记录,则无法访问下一个结点


    图解:

    ①第一次连接:

    在这里插入图片描述

    ②第二次连接:

    在这里插入图片描述

    ③第三次连接:

    在这里插入图片描述

我们可以看到,这样就逐步实现了单链表的后段逆置操作


代码实现:

	q = p->next;  //q指向后段的首结点
	p->next = NULL;

	LNode* r; //每次都指向q的下一个结点
	while (q != NULL) {
		r = q->next; //记录
		q->next = p->next; //相当于将单链表箭头反向
		p->next = q;
		q = r; //移动至下一结点
	}


3. 重排单链表

在完成上述操作后,我们就可以对前段和后段进行交替插入,即完成单链表的重排啦~

算法思路:

  1. s s s指向前段的首结点, q q q指向后段的首结点,中间指针 p p p指向 N U L L NULL NULL

    注意:

    这里中间指针 p p p指向 N U L L NULL NULL的操作很重要!!由于中间结点(两个或一个)在重排后一定是不动的,所以中间结点或中间结点的 next在重排后会变为尾结点,因此必须使其指向 NULL,相当于特判,否则最后打印单链表时会进入死循环


  1. 接下来就是插入操作,即不断让当前 q q q指向的结点插入到 s s s结点后,直至 q q q指向 N U L L NULL NULL即后段结点全部处理完毕

    在这里插入图片描述


代码实现:

	q= p->next; //q重新指向重排后的后段首结点
	LNode* s = L->next; //s指向前段的首结点
	p->next = NULL; //这里很重要,让中间结点指向NULL,否则会进入死循环

	while (q != NULL) { //当后段还有结点没被重排
		r = q->next; //记录下一结点——防止重排后丢失
		//插入
		q->next = s->next;
		s->next = q;
		s = q->next; //s移动至下一个
		q = r; //q移动至下一个
	}


完整代码实现:

#include<iostream>
using namespace std;

typedef struct LNode {
	int data;
	struct LNode* next;
}LNode,*LinkList;

//0.初始化
void InitList(LinkList& L) {
	L = (LNode*)malloc(sizeof(LNode)); //定义头结点
	L->next = NULL;
	LNode* p = L;

	int x;
	while (cin >> x) {
		LNode* s = (LNode*)malloc(sizeof(LNode));
		s->data = x;
		p->next = s;
		p = s;
		if (cin.get() == '\n')
			break;
	}
	p->next = NULL;
}


//重排
void reset(LinkList& L) {
	//1.找到中间结点
	LNode* p = L, * q = L; //p,q初始都指向头结点
	while (q->next != NULL) {
		p = p->next;
		q = q->next;
		if (q->next != NULL) //q每走一步都要先判断
			q = q->next;
	}
	//最终p指向中点,q指向尾结点

	//2.单链表后段逆置
	q = p->next;  //q指向后段的首结点
	p->next = NULL;

	LNode* r; //每次都指向q的下一个结点
	while (q != NULL) {
		r = q->next; //记录
		q->next = p->next; //相当于将单链表箭头反向
		p->next = q;
		q = r; //移动至下一结点
	}

	//3.重排插入结点
	q= p->next; //q重新指向重排后的后段首结点
	LNode* s = L->next; //s指向前段的首结点
	p->next = NULL; //这里很重要,让中间结点指向NULL,否则会进入死循环

	while (q != NULL) { //当后段还有结点没被重排
		r = q->next; //记录下一结点——防止重排后丢失
		//插入
		q->next = s->next;
		s->next = q;
		s = q->next; //s移动至下一个
		q = r; //q移动至下一个
	}
}

void Print(LinkList& L) {
	LNode* p = L;
	while (p->next != NULL) {
		p = p->next;
		cout << p->data << " ";
	}cout << endl;
}

int main() {
	LinkList L;
	cout << "请输入单链表的元素值:" << endl;
	InitList(L);

	cout << "原始链表为:" << endl;
	Print(L);

	//重排
	reset(L);
	cout << "重排后链表为:" << endl;
	Print(L);

	system("pause");
	return 0;
}

输出结果:

在这里插入图片描述



🎇这是一道关于单链表操作的真题,很有思考价值,可以反复练习噢~🎇

如有错误,欢迎指正~!

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pr安装缺少VCRUNTIME140.dll怎么办?这三个修复方案可以解决

在我们安装pr的时候&#xff0c;遇到缺少VCRUNTIME140.dll怎么办&#xff1f;vcruntime140.dll是一个Windows动态链接库&#xff0c;其主要功能是为C/C编译的程序提供运行时支持。这些库包括输入/输出函数、数学函数、字符串函数等等。因此&#xff0c;如果您的计算机缺少vcrun…

【接口自动化测试】一步一步教你搭建接口环境

要做接口测试&#xff0c;我们得搭建一套本地可以运行的接口环境。这次我选择了一个搭建容易&#xff0c;适合学习的系统——学生管理系统。 Python安装 这套管理系统是Python代码写的&#xff0c;因此需要Python环境。 安装挺无脑的&#xff0c;按照我提供的安装包和方法装…

windows下PC端小程序抓包--FiddlerCharles

目录 引言 【背景说明】 【操作说明】 【总结】 引言 大家好&#xff0c;你是否曾经遇到过想要抓取Windows下PC端小程序的网络请求数据&#xff0c;但不知道该用什么工具呢&#xff1f; 今天我要介绍的Fiddler和Charles两款工具&#xff0c;可帮助你轻松切入小程序网络请…

MySQL数据库 7.图形化界面工具DataGrip基础应用教学

目录 前言&#xff1a; DataGrip安装界面&#xff1a; 利用DataGrip创建数据库&#xff1a; 利用DataGrip为数据库创建表&#xff1a; 利用datagrip修改表&#xff1a; 添加元素&#xff1a; 结束&#xff01; 前言&#xff1a; 在之前我们一直接触的是MySQL命令行语句开…

4.3 最优装载

博主简介&#xff1a;一个爱打游戏的计算机专业学生博主主页&#xff1a; 夏驰和徐策所属专栏&#xff1a;算法设计与分析 1.什么是贪心算法的最优装载问题&#xff1f; 最优装载问题&#xff08;Bin Packing Problem&#xff09;是一个经典的组合优化问题&#xff0c;涉及将一…

【Linux】-编译器-gcc/g++使用以及动态库和静态库的介绍(以及解决sudo失败的方法)

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树 ❤️‍&#x1fa79;作者宣言&#xff1a;认真写好每一篇博客 &#x1f4a8;作者gitee:gitee &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点…

iOS证书(.p12)和描述文件(.mobileprovision)申请

目录 iOS证书(.p12)和描述文件(.mobileprovision)申请文末扩展&#xff08;UDID获取、添加测试设备&#xff09; 说明&#xff1a;本文申请证书、描述文件转载自 uniapp官网   iOS证书(.p12)和描述文件(.mobileprovision)申请      官网会时不时更新&#xff0c;如有疑问&…

《Apollo 智能驾驶进阶课程》二、 高精地图

1. 高精地图与自动驾驶的关系 1.1 高精地图与自动驾驶 L3级别以上才需要高精地图 1.2 什么是高精地图 1.3 高精地图与导航地图 1.4 高精地图-基础模块 高精地图与定位模块的关系 现在主流的自动驾驶的定位方案有两种&#xff1a;一种是基于点云&#xff0c;另一种是基于C…

投票系统(前后端分离)

1.投票系统的介绍 投票系统是一种用于组织选举和投票的软件系统&#xff0c;它可以帮助政府、企业、组织和社区等各种机构进行公正、透明和高效的投票活动。投票系统的主要功能包括&#xff1a;选民身份验证、投票管理、计票和结果公布等。 选民身份验证是指投票系统可以通过…

SpringCloud Sleuth/Zipkin学习

SpringCloud Sleuth/Zipkin 文章目录 SpringCloud Sleuth/Zipkin1 Sleuth/Zipkin 简介2 Sleuth/ZipKin-搭建链路监控实例 1 Sleuth/Zipkin 简介 在微服务框架中&#xff0c;一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用, 来协同产生最后的请求结果&…

电脑右键删除的文件如何恢复?提供了4种方法

电脑上不小心删除文件是很常见的一件事。比如在使用右键删除的情况下&#xff0c;但是&#xff0c;误删并不代表永远丧失这个文件&#xff0c;因为我们可以通过一些方法来恢复右键删除的文件。本文提供了4种方法&#xff0c;你可以根据具体的数据丢失情况选择合适的方法。 方法…

【Python】列表 List ③ ( 查询操作 / 修改操作 | 列表查询操作 List#index | 修改列表指定位置元素值 )

文章目录 一、列表查询操作1、List#index 函数简介2、代码示例 - 列表查询3、列表查询 ValueError 报错 二、修改列表指定索引元素1、语法简介2、代码示例 - 使用正向 / 反向索引修改指定元素 一、列表查询操作 1、List#index 函数简介 列表 List 查询功能 , 通过 List#index 函…

PyTorch 深度学习 || 专题一:神经网络基础

神经网络基础 神经网络是一门重要的机器学习技术。它是目前最为火热的研究方向–深度学习的基础。学习神经网络不仅可以让你掌握一门强大的机器学习方法&#xff0c;同时也可以更好地帮助你理解深度学习技术。 神经网络是一种模拟人脑的神经网络以期能够实现类人工智能的机器…

【JAVA】双向链表详解

【JAVA】双向链表详解 双向链表的定义双向链表的初步实现&#xff08;准备&#xff09;双向链表的操作一. 打印链表二. 得到链表长度三. 插入操作3.1 头插法3.2 尾插法3.3 任意位置插入 四. 删除操作4.1 删除第一次出现为key的节点&#xff08;3种情况&#xff09;4.2 删除所以…

Vue--》Vue3打造可扩展的项目管理系统后台的完整指南(四)

今天开始使用 vue3 ts 搭建一个项目管理的后台&#xff0c;因为文章会将项目的每一个地方代码的书写都会讲解到&#xff0c;所以本项目会分成好几篇文章进行讲解&#xff0c;我会在最后一篇文章中会将项目代码开源到我的GithHub上&#xff0c;大家可以自行去进行下载运行&…

保姆级别ps bate版本下载

前言&#xff1a;最近的ps bete版本在抖音也是上了热搜&#xff0c;时不时就能刷到一个&#xff0c;相信大家也知道ai带来的魅力&#xff0c;真的很强&#xff0c;那我们就开始安装教程吧。 ​过程&#xff1a; 先打开链接&#xff1a;Adobe Creative Cloud | Details and pr…

使用外部工具横向移动

Smbexe、Psexec Psexec PsExec是一种轻巧的telnet代替品&#xff0c;可让您在其他系统上执行进程&#xff0c;并为控制台应用提供完整的交互性&#xff0c;无需手动安装客户端软件。 原理&#xff1a; 1、ipc$连接&#xff0c;释放Psexesvc.exe 2、OpenSCManager打开受害者…

如何使用ChatGPT自带插件

OpenAI的插件将ChatGPT连接到第三方应用程序。这些插件使ChatGPT能够与开发者定义的API进行交互&#xff0c;增强ChatGPT的能力&#xff0c;并使其能够执行广泛的操作。插件使ChatGPT能够做如下事情&#xff1a; 获取实时信息&#xff1b;例如&#xff0c;体育比分&#xff0c…

采样率(压缩比)对OMP算法的影响

前面详细分析了OMP重构算法原理以及实现&#xff0c;本篇主要分析采样率对OMP算法的影响。 OMP重构算法的流程为 以下分析采样率对OMP算法的影响。 先对一维信号重构进行分析&#xff0c;表1是OMP算法中采样率对重构的MSE和时间的对应表格&#xff1a; 表1&#xff1a;MP算法采…

04-Springbooot与Spring Cloud Alibaba搭建后端架构

1、创建Springbooot父工程 1.1、使用快速创建Springbooot工程的方式&#xff1a; 1.2、项目使用Maven进行管理 settings.xml&#xff0c;配好了阿里镜像 02-maven的安装配置_NikoWord的博客-CSDN博客 2、项目初始化配置 01-IDEA使用技巧_NikoWord的博客-CSDN博客 04-设置…