2019_41 考研408
2019年(单链表)
41.(13分)设线性表

采用带头结点的单链表保存,链表中的结点定义如下:
typedef struct node {
int data;
struct node* next;
}NODE;
请设计一个空间复杂度为O(1)且时间上尽可能高效的算法,重新排列L中的各结点,得到线性表L'=(q,a,,a,an-1,as,an-2y…)。要求:
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。
(3)说明你所设计的算法的时间复杂度。
思路:因为题目要求要空间复杂度为O(1),所以我们不能再额外申请空间了,然后再找到链表的中间结点,将其一分为二,分为L和L2的单链表,并将L2链表进行原地逆置,最后再将L和L2进行混合合并。
一、找到中间结点,并一分为二。
思路:定义两个指针p1和p2,p1指针每次走两步,p2指针每次走一步,当p1指针走到最后,p2指针必定走到中间结点。(写代码的过程中还应该注意总结点是奇数还是偶数)

代码段:
void find_middle(LinkList L,LinkList &L2) //寻找链表中间结点,并设置好L2链表
{L2 = (LinkList)malloc(sizeof(LNode)); //设置第二条链表的头结点 LinkList pcur,ppre; //双指针法,pcur跨两步,ppre跨一步。 ppre = pcur = L->next; //一开始都指向第一个结点,即首元结点 while(pcur) {pcur = pcur->next;if(pcur == NULL) //防止pcur为空 {break;}pcur = pcur->next; //若此处pcur为空,则不满足循环条件 if(pcur == NULL) //为了使得偶数个,ppre依然指向a1,a2到a6中的a3结点 {break;}ppre = ppre->next;}L2->next = ppre->next; //由L2头结点指向后面一半链表,L2的第一个结点是此时ppre所指向的结点 ppre->next = NULL; //此时的ppre为前一半链表的最后一个结点,最后一个结点的指针域应该为NULL
}
二、将L2原地逆置
思路:分别定义3个指针r、s、t,让r、s、t分别指向前三个结点,再让第二个结点指向第一个结点,然后r、s、t同时向后移动一位,再让第三个结点指向第二个结点,然后r、s、t同时向后移动一位,如此往复循环,当t为null时循环结束。因为原有链表的头结点变成链表最后一个结点,最后一个结点应该指向NULL,最后让L2头结点指向新的首元结点s。

代码段:
void reverse(LinkList L2) //逆转。因为L2的头结点不会发生改变
{LinkList r,s,t;r = L2->next; //一开始r指向首元结点 if(r == NULL){return ;//链表为空 }s = r->next; //一开始r指向s if(s == NULL){return;//链表只有1个结点 } t = s->next; //一开始让s指向twhile(t){s->next = r; //原地逆置,让s指向r r = s; //以下3句,是3个指针同时向后移动一位 s = t;t = t->next; } s->next = r;L2->next->next = NULL;//逆置后,原本链表的第一个结点的指针域为空。即逆置后新链表的最后一个结点。 L2->next = s; //此时s是逆置后链表的第一个结点,L2的头结点应该指向它
}
三、将L与L2进行混合合并
思路:将L与L2链表合并,合并时分别轮流放入一个结点。定义3个指针pc、p、q,一开始指针pc指向L链表的首元结点,指针p指向L链表的第二结点,指针q指向L2链表的首元结点。并且让pc指针始终指向合并后新链表的尾部,使用p指针始终指向链表L待放入的结点,q指针始终指向链表L2待放入的结点。

代码段:
void merge(LinkList L,LinkList L2) //将L与L2混合并合并
{LinkList pcur,p,q;pcur = L->next; //pcur一开始指向L链表的首元结点。pcur始终指向组合后新链表的链表尾p = pcur->next; //p指向L链表的第二个结点。p用来遍历L链表。 q = L2->next; //q指向L2链表的首元结点。q用来遍历L2的链表。 while(p!=NULL && q!=NULL) //以下步骤画图,就会非常的直观。 {pcur->next = q;q = q->next;pcur = pcur->next;pcur->next = p;p = p->next;pcur = pcur->next; } //任何一个链表都可能剩余一个结点,放进来即可。 if(p!=NULL){pcur->next = p;}if(q!=NULL){pcur->next = q;}
}
总代码:
#include<stdio.h> //2019年考研408真题,第41题
#include<stdlib.h>typedef int ElemType;
typedef struct LNode{ElemType data; //数据域 struct LNode *next; //指针域
}LNode,*LinkList;void list_tail_insert(LinkList &L) //尾插法建立链表
{L = (LinkList)malloc(sizeof(LNode));L->next = NULL;ElemType x;scanf("%d",&x);LNode *s;//用来指向申请的新结点LNode *r=L;//r始终指向链表尾部while(x != 999){s = (LinkList)malloc(sizeof(LNode));s->data = x;r->next = s; //r->next指向s结点r = s; //r要指向新的尾部 scanf("%d",&x); } r->next = NULL; //让尾结点的next为NULL
}void find_middle(LinkList L,LinkList &L2) //寻找链表中间结点,并设置好L2链表
{L2 = (LinkList)malloc(sizeof(LNode)); //设置第二条链表的头结点 LinkList pcur,ppre; //双指针法,pcur跨两步,ppre跨一步。 ppre = pcur = L->next; //一开始都指向第一个结点,即首元结点 while(pcur) {pcur = pcur->next;if(pcur == NULL) //防止pcur为空 {break;}pcur = pcur->next; //若此处pcur为空,则不满足循环条件 if(pcur == NULL) //为了使得偶数个,ppre依然指向a1,a2到a6中的a3结点 {break;}ppre = ppre->next;}L2->next = ppre->next; //由L2头结点指向后面一半链表,L2的第一个结点是此时ppre所指向的结点 ppre->next = NULL; //此时的ppre为前一半链表的最后一个结点,最后一个结点的指针域应该为NULL
} void reverse(LinkList L2) //逆转。因为L2的头结点不会发生改变
{LinkList r,s,t;r = L2->next; //一开始r指向首元结点 if(r == NULL){return ;//链表为空 }s = r->next; //一开始r指向s if(s == NULL){return;//链表只有1个结点 } t = s->next; //一开始让s指向twhile(t){s->next = r; //原地逆置,让s指向r r = s; //以下3句,是3个指针同时向后移动一位 s = t;t = t->next; } s->next = r;L2->next->next = NULL;//逆置后,原本链表的第一个结点的指针域为空。即逆置后新链表的最后一个结点。 L2->next = s; //此时s是逆置后链表的第一个结点,L2的头结点应该指向它
}void merge(LinkList L,LinkList L2) //将L与L2混合并合并
{LinkList pcur,p,q;pcur = L->next; //pcur一开始指向L链表的首元结点。pcur始终指向组合后新链表的链表尾p = pcur->next; //p指向L链表的第二个结点。p用来遍历L链表。 q = L2->next; //q指向L2链表的首元结点。q用来遍历L2的链表。 while(p!=NULL && q!=NULL) //以下步骤画图,就会非常的直观。 {pcur->next = q;q = q->next;pcur = pcur->next;pcur->next = p;p = p->next;pcur = pcur->next; } //任何一个链表都可能剩余一个结点,放进来即可。 if(p!=NULL){pcur->next = p;}if(q!=NULL){pcur->next = q;}
}void print_list(LinkList L) //打印输出链表
{L = L->next;while(L != NULL){printf("%3d",L->data);L = L->next;}printf("\n");
}int main()
{LinkList L; //L是头指针 LinkList search; //用来存储拿到的某一个结点 list_tail_insert(L); //输入数据可以为数据 print_list(L);//链表打印LinkList L2=NULL; find_middle(L,L2); //寻找中间结点,并返回第二条链表 。只有一个结点时,L2中是没有结点的 printf("-----------------------------\n");print_list(L);print_list(L2);printf("-----------------------------\n");reverse(L2);print_list(L2);printf("-----------------------------\n");merge(L,L2);free(L2);print_list(L);return 0;
}
相关文章:

2019_41 考研408
2019年(单链表)41.(13分)设线性表采用带头结点的单链表保存,链表中的结点定义如下:typedef struct node {int data;struct node* next;}NODE;请设计一个空间复杂度为O(1)且时间上尽可能高效的算法,重新排列L中的各结点,得到线性表L(q,a,,a,an…...

Linux账号与用户组
目录 用户标识符:UID与GID 用户账号 /etc/passwd文件结构 1、账号名称 2、密码 3、UID 4、GID 5、用户信息说明栏 6、家目录 7、shell /etc/shadow文件结构 1、账号名称 2、密码 3、最近修改密码的日期 4、密码不可被修改的天数(与第三字…...

有趣的Hack-A-Sat黑掉卫星挑战赛——定位卫星Jackson
国家太空安全是国家安全在空间领域的表现。随着太空技术在政治、经济、军事、文化等各个领域的应用不断增加,太空已经成为国家赖以生存与发展的命脉之一,凝聚着巨大的国家利益,太空安全的重要性日益凸显[1]。而在信息化时代,太空安…...

JAVA集合专题3 —— vector + LinkedList + Set
目录vector的特点LinkedList底层结构模拟双向链表比较ArrayList和LinkedListSet接口基本介绍Set接口的遍历方式Set接口实现类对象的特点Set接口实现类HashSet模拟HashSet/HashMap的底层结构vector的特点 Vector底层是一个对象数组Vector是线程同步的,即线程安全的&…...

Scout:一款功能强大的轻量级URL模糊测试与爬取工具
关于Scout Scout是一款功能强大的轻量级URL模糊测试与爬取工具,可以帮助广大研究人员进行URL模糊测试,并爬取目标Web服务器中难以扫描发现的VHSOT、文件和目录等资源。 项目中包含了一个完整的字典文件,并尽可能地提供了更多的便携性&#…...

leaflet 解决marker呈现灰色边框的问题
第052个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet示例中处理marker外面有灰色边框的问题,请看未处理会后的图片。 处理后的结果非常满意,不再显示灰色边框。处理方法参考源代码。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意…...
MySQL JSON类型字段的查找与更新
MySQL 提供了丰富的函数用于 JSON 类型字段的查找与更新,详见官方文档。 创建一个表 t1,basic_info 字段为JSON类型: CREATE TABLE t1 (id int(11) NOT NULL AUTO_INCREMENT,basic_info json DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CH…...

element Ui树状图控件 spring boot Vue 实现角色授权功能
目录 前言: 二. element ui 2.1官网提供的核心代码 三.表结构 编辑 四.后端 4.1功能分析 4.2实体类 4.3 查询全部权限显示的结果 4.2修改角色权限的后台方法 五.vue 5.0代码总览 5.1树形图 5.2所需要的绑定数据 5.3所需方法 前言: 先上图…...

已解决sc delete MongoDB卸载MongoDB拒绝访问。
已解决sc delete MongoDB卸载MongoDB拒绝访问。 文章目录报错问题报错翻译报错原因解决方法联系博主免费帮忙解决报错报错问题 粉丝群里面的一个小伙伴遇到问题跑来私信我,想卸载MongoDB数据库,但是发生了报错(当时他心里瞬间凉了一大截&…...

python的opencv操作记录11——阈值分割
文章目录传统图像处理分割阈值分割一个应用场景opencv库中的阈值分割固定阈值THRESH_OTSU 大津法阈值自适应阈值传统图像处理分割 现在提到图像分割,很多人会直接想到当前火爆的深度学习的各种分割网络,比如实例分割,语义分割等。其实在传统…...

Python-项目实战--飞机大战-英雄登场(7)
目标设计英雄和子弹类使用pygame.key.get_pressed()移动英雄发射子弹1.设计英雄和子弹类1.1英雄需求游戏启动后,英雄出现在屏幕的水平中间位置,距离屏幕底部120像素英雄每隔0.5秒发射一次子弹,每次连发三枚子弹英雄默认不会移动,需…...

寒假安全作业nginx-host绕过实例复现
1.测试环境搭建 LNMP架构的话,肯定就是linux、nginx、mysql、php四大组件。在后面的复现中我们还会用到https的一部分知识,故这里的nginx就需要使用虚拟主机并且配置https证书,且具有php解析功能。 1.1 基础nginx配置 #1.创建web目录 mkdir …...

RocketMQ-消息消费模式 顺序消费
RocketMQ-消息消费模式 顺序消费RocketMQ-消息消费模式集群模式集群模式的演示(本身就默认)Rocketmq存储队列广播模式顺序消费如何改实现顺序消费RocketMQ-消息消费模式 集群模式 在消费模式为集群的情况下,如果机器是集群的,消息只会给集群中的其中一台机器消费到 集群模…...

一、Java并发编程之线程、synchronized
黑马课程 文章目录1. Java线程1.1 创建和运行线程方法一:Thread方法二:Runnable(推荐)lambda精简Thread和runnable原理方法三:FutureTask配合Thread1.2 查看进程和线程的方法1.3 线程运行原理栈与栈帧线程上下文切换1.…...

12.hadoop系列之MapReduce分区实践
本文我们学习MapReduce默认分区以及自定义分区实践 当我们要求将统计结果按照条件输出到不同文件(分区),比如按照统计结果将手机归属地不同省份输出到不同文件中(分区) 1.默认Partitioner分区 public class HashPartitioner<K, V> extends Partitioner<…...

有了独自开,一个人就是一个团队
文章目录 简单介绍优点 优秀案例平台福利总结 简单介绍 独自开是一个基于商品与服务交易全流程的PaaS开发平台。对于开发者,独自开可以协助开发者一个人独自开发一套系统。 优点 独自开有独创的分层标准化平台架构,可以满足系统的任何个性化需求。 …...

web期末复习 2023.02.11
文章目录Web 的概念Web 组成用户通过浏览器请求资源的过程:HTML 超文本标记语言CSS插入样式表的方法有三种:对象,类,实例一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:JavaScript 用法什么是 Java Server Pages?JSP 注释JSP 的 J…...
第44章 用户密码实体及其约束规则的定义实现
1 说明: 由当前程序需要兼容实现多种用户密码的加密操作,所以必须把“CustomerPassword”定义为实体类,该类用于用于把加密方式、密钥及其加密后的密码持久化到“CustomerPassword”表中,以便用为用户登录操作提供验证支撑。 如果…...

聊聊并发与锁
持续坚持原创输出,点击蓝字关注我吧1.并发与并行并发可以充分地利用 CPU 资源,一般都会使用多线程实现。多线程的作用是提高任务的平均执行速度,但是会导致程序可理解性变差,编程难度加大。关于对并发与并行的概念,大家…...

开源项目 —— 原生JS实现斗地主游戏 ——代码极少、功能都有、直接粘贴即用
目录 效果如下 目录结构 GameEntity.js GrawGame.js konva.min.js PlayGame.js veriable.js index.html 结语: 前期回顾 卡通形象人物2 写代码-睡觉 丝滑如德芙_0.活在风浪里的博客-CSDN博客本文实现了包含形象的卡通小人吃、睡、电脑工作的网页动画https://…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...