【考研复习】24王道数据结构课后习题代码|2.3线性表的链式表示

文章目录

  • 总结
  • 01 递归删除结点
  • 02 删除结点
  • 03 反向输出
  • 04 删除最小值
  • 05 逆置
  • 06 链表递增排序
  • 07 删除区间值
  • 08 找公共结点
  • 09 增序输出链表
  • 10 拆分链表--尾插
  • 11 拆分链表--头插
  • 12 删除相同元素
  • 13 合并链表
  • 14 生成含有公共元素的链表C
  • 15 求并集
  • 16 判断子序列
  • 17 判断循环链表是否对称
  • 18 两个循环链表链接
  • 19 找最小结点并删除
  • 21 判断单链表是否有环
  • 22 【2009真题】找倒数第k个元素
  • 23 【2012真题】相同后缀找起始位置
  • 24 【2015真题】删除绝对值相同
  • 25 【2019真题】重新排列链表

总结

  • 删除结点:1、2、4
  • 就地逆置:5、
  • 合并链表
  • 分解链表:10、11、
  • 去除重复元素:12、
  • 并集:14、15
  • 循环链表:17、18、19、20
  • 头插法、尾插法重点基础必掌握。
  • 判断是否有环:21

01 递归删除结点

用函数递归调用删除结点。

void deletex(linklist &L,int x){if(L==NULL) return;lnode *p;if(L->data==x){p=L;L=L->next;free(p);deletex(L,x);}else deletex(L->next,x);
}

02 删除结点

注意删除结点的时候可能断链。

void deletex2(linklist &L,int x){lnode *p=L->next,*pre=L,*q;while(p){if(p->data==x){q=p;p=p->next;pre->next=p;free(q);}else{pre=p;p=p->next;}}
}

03 反向输出

利用函数调用的特性反向输出。

void r_print(linklist L){if(L!=NULL){r_print(L->next);cout<<(L->data)<<" ";}else return;
}
void r_ignore_node(linklist L){if(L->next!=NULL){r_print(L->next);}
}

04 删除最小值

  1. 设置保留最小值的指针和其前驱
  2. 每次更新最小值
void delete_min(linklist L){lnode *p=L->next,*pre=L;lnode *minp=p,*minpre=pre;while(p){if(p->data<minp->data){minp=p;minpre=pre;}else{p=p->next;pre=pre->next;}}minpre->next=minp->next; //删除最小值结点free(minp);
}

05 逆置

很重要的基础:头插法

void head(linklist &L){lnode *p=L->next,*r;L->next=NULL;while(p){r=p->next;      //记录下一结点p->next=L->next;L->next=p;p=r;}
}

06 链表递增排序

使用插入排序的思想,将头置空之后,扫描最小元素,然后使用尾插法插入头中。

void insert_sort(linklist &L){lnode *p=L->next,*r=p->next,*pre;p->next=NULL;p=r;while(p){r=p->next;pre=L;while(pre->next!=NULL&&pre->next->data<p->data){pre=pre->next;}p->next=pre->next;pre->next=p;p=r;}
}

07 删除区间值

2题的删除代码,改下if语句即可。

void delete_x_m_n(linklist &L,int m, int n){lnode *p=L->next,*pre=L,*q;while(p){if(p->data<n&&p->data>m){q=p;p=p->next;pre->next=p;free(q);}else{pre=p;p=p->next;}}
}

08 找公共结点

linklist find_same_dot(linklist L1,linklist L2){linklist longlist, shortlist;int dist=0;int len1=length(L1),len2=length(L2);if(len1>len2){longlist=L1;shortlist=L2;dist=len1-len2;}else{longlist=L2;shortlist=L1;dist=len2-len1;}while(dist--) longlist=longlist->next;while(longlist){if(longlist->data==shortlist->data&&longlist->next->data==shortlist->next->data)return longlist;else{longlist=longlist->next;shortlist=shortlist->next;}}return NULL;
}

09 增序输出链表

6题

void min_output(linklist L){while(L->next){lnode *pre=L,*p=L->next;lnode *minpre=pre, *minp=p;while(p){if(p->data<minp->data){minp=p;minpre=pre;}p=p->next;pre=pre->next;}cout<<minp->data<<" ";minpre->next=minp->next;free(minp);}
}

10 拆分链表–尾插

第一种方法是在A中直接删除。

linklist split_1_1(linklist &A){linklist B = (linklist)malloc(sizeof(lnode));B->next=NULL;lnode *p=A->next,*ra=A;lnode *rb=B,*q;while(p){//向后移一个ra=p;p=p->next;//从A中删除结点q=p;ra->next=p->next;p=p->next;//利用尾插法将结点插入B中rb->next=q;rb=rb->next;}ra->next=NULL;rb->next=NULL;return B;
}

第二种方法是把A的头拿下来,再选最小的排在A后。=尾插==

linklist split_1_2(linklist &A){linklist B = (linklist)malloc(sizeof(lnode));B->next=NULL;lnode *p=A->next,*ra=A;lnode *rb=B;//把表头摘下来A->next=NULL;while(p){//结点给Ara->next=p;ra=ra->next;p=p->next;//结点给Brb->next=p;rb=rb->next;p=p->next;}ra->next=NULL;rb->next=NULL;return B;
}

11 拆分链表–头插

第一种方法同上

linklist split_1_1(linklist &A){linklist B = (linklist)malloc(sizeof(lnode));B->next=NULL;lnode *p=A->next,*ra=A;lnode *rb=B,*q;while(p){//向后移一个ra=p;p=p->next;//从A中删除结点q=p;ra->next=p->next;p=p->next;//利用头插法将结点插入B中q=p->next;p->next=rb->next;rb->next=p;p=q;}ra->next=NULL;return B;
}

第二种方法同上

linklist split_2_1(linklist &A){linklist B = (linklist)malloc(sizeof(lnode));B->next=NULL;lnode *p=A->next,*ra=A;lnode *rb=B,*q;//把表头摘下来A->next=NULL;while(p){//结点给Ara->next=p;ra=ra->next;p=p->next;//结点给Bif(p){q=p->next;p->next=rb->next;rb->next=p;p=q;}}ra->next=NULL;//b是头插法所以最后指向是为NULLreturn B;
}

12 删除相同元素

简单代码,只不过要注意的p是要删除结点的前一个结点,判断的时候别判断错了。

void del_same(linklist &L){lnode *p=L->next,*q;if(p==NULL) return;while(p->next){q=p->next;if(p->data==q->data){p->next=q->next;free(q);}else{p=p->next;}}
}

13 合并链表

void merge(linklist &L1,linklist &L2)
{lnode *p1=L1->next,*p2=L2->next,*r;L1->next=NULL;while(p1&&p2){if(p1->data<=p2->data){r=p1->next;p1->next=L1->next;L1->next=p1;p1=r;}else{r=p2->next;p2->next=L1->next;L1->next=p2;p2=r;}}if(p1) p2=p1;while(p2){r=p2->next;p2->next=L1->next;L1->next=p2;p2=r;}free(L2);
}

14 生成含有公共元素的链表C

  1. 两个链表分别遍历,比较值头插入C中
linklist merge_same(linklist &A,linklist &B){lnode *p=A->next,*q=B->next;lnode *r,*s;linklist C = (linklist)malloc(sizeof(lnode));r=C;while(p&&q){if(p->data<q->data){p=p->next;}else if(p->data>q->data){q=q->next;}else{s=(lnode *)malloc(sizeof(lnode *));s->data=p->data;r->next=s;r=r->next;p=p->next;q=q->next;}}r->next=NULL;return C;
}

15 求并集

  1. 值不相同时分别删除A和B中的值
  2. 相同时删除B中的值
  3. 基础就是删除代码
void intersection(linklist &A,linklist &B){lnode *p=A->next,*q=B->next;lnode *r=A,*temp;while(p&&q){if(p->data<q->data){temp=p;p=p->next;free(temp);}else if(p->data>q->data){temp=q;q=q->next;free(temp);}else{//相等的时候保留A中相同元素r->next=p;r=r->next;p=p->next;//删除B中相同的元素temp=q;q=q->next;free(temp);}}while(p){temp=p;p=p->next;free(temp);}while(q){temp=q;q=q->next;free(temp);}r->next=NULL;
}

16 判断子序列

朴素kmp,也有所说bf的

bool simple_kmp(linklist &A,linklist &B){lnode *p=A->next,*q=B->next,*r=A->next;while(p&&q){if(p->data!=q->data){r=r->next;p=r;q=A->next;}else{p=p->next;q=q->next;}}if(q) return false;else return true;
}

17 判断循环链表是否对称

循环链表就方便了,能找前驱和后继,两个指针同时移动判断值即可。

bool symmetry(linklist L)
{lnode *p=L->next,*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;
}

18 两个循环链表链接

注意头尾即可

void add(linklist &h1,linklist &h2)
{lnode *p=h1->next,*q=h2->next;while(p->next!=h1){p=p->next;}while(q->next!=h2){q=q->next;}p->next=h2->next;//初始化的链表带头结点,若不带h2即可q->next=h1;
}

19 找最小结点并删除

  1. 遍历链表每次输出最小结点然后删除即可
    相同代码见9题
void find_min(linklist &L){while(L->next!=L){lnode *pre=L,*p=L->next;lnode *minpre=pre, *minp=p;while(p!=L){if(p->data<minp->data){minp=p;minpre=pre;}p=p->next;pre=pre->next;}cout<<minp->data<<" ";minpre->next=minp->next;free(minp);}free(L);
}

21 判断单链表是否有环

  1. 两步走总能相遇,按照这个作为遇到的条件找相遇点和入环结点。
    25题也是两步走。
lnode* findd(lnode *L)
{lnode *f=L,*s=L;while(s!=NULL&&f->next!=NULL){s=s->next;f=f->next->next;if(s->data==f->data) break; //可以直接设置指针,但是我初始化的有单链表为int a[15]={1,2,3,4,5,6,7,8,9,4,5,6,7,8,9};故用这种方法}if(s==NULL||f->next==NULL) return NULL;lnode *p=L,*q=s;while(p->data!=q->data){p=p->next;q=q->next;}return p;
}

22 【2009真题】找倒数第k个元素

  1. 相当于用长度为k的尺子比着找,最右端到尾部的时候,最左端就是倒数第k个元素。
int findk(linklist &L, int k){lnode *p=L,*q=L;int count=0;while(p){if(count<k) count++;else q=q->next;p=p->next;}if(count<k) return 0;else cout<<"kth to last position: "<<q->data;return 1;
}

23 【2012真题】相同后缀找起始位置

  1. 把尾部排齐:两个指针遍历链表,长度相同时找到相同时尾部对齐了
  2. 排齐之后遍历两个链表找第一个不相同的位置,该位置的下一个位置就是相同后缀的位置
typedef struct lnode{int data;struct lnode *next;
}lnode,*linklist;
lnode * find_addr(linklist str1, linklist str2){lnode *p,*q;int m=length(str1);int n=length(str1);for(p=str1;m>n;m--) p=p->next;for(q=str2;m<n;n--) q=q->next;while (p->next!=NULL&&q->next!=NULL){p=p->next;q=q->next;}return p->next;
}

24 【2015真题】删除绝对值相同

要求时间复杂度尽可能高➡️空间换时间

  1. 数组存查找状态:0表示绝对值未找到,1表示找到,第二次找到的同时删除该结点
  2. 注意动态分配数组的使用(静态数组试了试内存超出,不知道是不是这个问题)
void same(linklist &L,int n)
{lnode *p=L;int *q;q=(int *)malloc(sizeof(int)*(n+1));for(int i=0;i<n+1;i++) *(q+i)=0;int s;lnode *f;while(p->next!=NULL){s=abs(p->next->data);if(*(q+s)==0) {*(q+s)=1;p=p->next;}else{f=p->next;p->next=f->next;free(f);}}free(q);
}

25 【2019真题】重新排列链表

  1. 两步走找中间结点
  2. 逆置后边链表:使用头插法
  3. 看成两个链表进行插入
    21也是两步走
void change(linklist &L){lnode *p,*q,*r,*s;p=q=L;while (q->next){p=p->next;q=q->next;if(q->next) q=q->next;}q=p->next;  //p现在在中间结点p->next=NULL;  //把后半段摘下来,逆置之后分别遍历两个链表插入指定位置while (q)  //头插法实现原地逆置{r=q->next;  //暂存后继结点q->next=p->next;  //将q结点放在头结点p之后p->next=q;q=r;}s=L->next;  //插入点q=p->next;  //后半段数据点p->next=NULL;  while(q){r=q->next;q->next=s->next;s->next=q;s=q->next;q=r;}
}

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

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

相关文章

Android Studio实现刮刮卡效果

代码和刮刮乐图片参考网络 实现效果 MainActivity import android.app.Activity; import android.os.Bundle;public class MainActivity extends Activity {Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentVi…

ruoyi-cloud微服务新建子模块

ruoyi-cloud微服务新建子模块 1、复制system模块 直接复制 modules下面已有的system模块&#xff0c;改名为 test 2、在modules下的 pom.xml文件中添加子模块 3、进入 test模块修改 pom.xml 把原有的system 修改成test 4、修改对应的包名、目录名和启动应用程序为test 5、修…

大学生口才培训需求分析

标题&#xff1a;大学生口才培训需求分析 摘要&#xff1a; 本论文旨在分析大学生口才培训的需求&#xff0c;通过对大学生口才培训的重要性、现状和挑战进行研究&#xff0c;并结合相关理论和实践经验&#xff0c;提出相应的培训需求和解决方案。通过本论文的研究&#xff0c…

介绍另外一个容器技术, Apptainer

一说到容器&#xff0c;我们往往会脱口而出&#xff0c; Docker&#xff0c; 实际上Docker 仅仅是Linux 容器化的一种&#xff0c; 今天介绍的Apptainer 就是另外一种容器技术。 那么Apptainer 具体是一个什么东西呢&#xff1f; 跟Docker 有什么区别呢&#xff1f; 首先&#…

【HarmonyOS】Java如何引用外部jar包

【关键字】 Java、引用jar包​ 【写在前面】 使用API6和API7开发HarmonyOS应用时&#xff0c;因为应用中只能引用SDK中开放的功能接口&#xff0c;但是部分jdk自带的接口功能在SDK中并未封装&#xff0c;要想在工程中使用jdk开放的接口功能&#xff0c;需要将jdk中的jar包通过…

Docker cp(CVE-2019-14271)漏洞复现与分析

安装 metarget安装有点问题&#xff0c;所以我们直接指定安装 可以用下面命令 查看包 apt-cache madison docker-ce 安装 apt-get install -y docker-ce5:19.03.0~3-0~ubuntu-bionic 原理 EXP metarget/writeups_cnv/docker-cve-2019-14271 at master Metarget/metarget G…

【TS第三讲】完善TS开发环境

文章目录 &#x1f31f; 写在前面&#x1f31f; ts-node&#x1f31f; nodemon&#x1f31f; nodemon文件类型&#x1f31f; nodemon文件范围&#x1f31f; 写在最后 &#x1f31f; 写在前面 &#x1f525;探索TypeScript世界&#xff0c;驭Vue3Ts潮流&#xff0c;开启前端之旅…

STM32--综述

文章目录 前言STM32简介STM32F103C8T6系统结构Keil软件安装注意事项新建工程操作流程 前言 本专栏将学习B站江协科技的STM32入门教程&#xff0c;通过自身理解和对老师的总结所写的博客专栏。 STM32简介 STM32是意法半导体&#xff08;STMicroelectronics&#xff09;公司推…

香山处理器跑仿真和跑FPGA两套环境配置过程小结

裸机ubuntu18.04上运行香山处理器&#xff08;南湖&#xff09;make verilog system program problem detected - sudo vi /etc/default/apport sudo apt install tree git cmake curl sudo apt install bison flex sudo apt install verilator sudo apt install default-jr…

intelJ IDEA\PHPStorm \WebStorm\PyCharm 通过ssh连接远程Mysql\Postgresql等数据库

最容易出错的地方是在general面板下的host&#xff0c;不应该填真实的host地址&#xff0c;而应该填localhost或者127.0.0.1 具体操作步骤见下图

Shopify平台Fulfillment业务模块升级

上图是销售订单、发货单与配送之间的关系图&#xff0c;销售订单可以创建多个发货单&#xff0c;多个发货单(不同销售订单)可以合并在一个配送订单进行发货 接口请求错误记录: 1. The api_client does not have the required permission(s). 2. Required parameter missing or…

特殊符号的制作 台风 示例 使用第三方工具 Photoshop 地理信息系统空间分析实验教程 第三版

特殊符号的制作 首先这是一个含有字符的&#xff0c;使用arcgis自带的符号编辑器制作比较困难。所以我们准备采用Adobe Photoshop 来进行制作符号&#xff0c;然后直接导入符号的图片文件作为符号 我们打开ps&#xff0c;根据上面的图片的像素长宽比&#xff0c;设定合适的高度…

FastAPI和Flask:构建RESTful API的比较分析

Python 是一种功能强大的编程语言&#xff0c;广泛应用于 Web 开发领域。FastAPI 和 Flask 是 Python Web 开发中最受欢迎的两个框架。本文将对 FastAPI 和 Flask 进行综合对比&#xff0c;探讨它们在语法和表达能力、生态系统和社区支持、性能和扩展性、开发工具和调试支持、安…

优橙内推黑龙江专场——5G网络优化(中高级)工程师

可加入就业QQ群&#xff1a;801549240 联系老师内推简历投递邮箱&#xff1a;hrictyc.com 内推公司1&#xff1a;中富通集团股份有限公司 内推公司2&#xff1a;北京电旗通讯技术股份有限公司 内推公司3&#xff1a;元道通信股份有限公司 中富通集团股份有限公司 中富通股…

ROS2系统学习番外篇2---用VSCode开发ROS2程序

在ROS2系统学习3—第一个“Hello World”程序—即工作空间创建与包创建中已经介绍了如何创建ROS的工作空间以及包。在开发大型工程时,往往需要在IDE下面进行开发,因此本篇介绍使用VSCode来搭建ROS2开发环境的方法。 首先用VSCode打开ROS2的工作空间。 使用快捷键编译ROS2 …

【springboot项目】在idea中启动报错合集

一、IDEA中报错 “Error running ‘Application‘: Command line is too long.“ 的解决办法 报错详情&#xff1a; Error running Application: Command line is too long.Shorten command line for Application or also for Spring Boot default configuration.报错原因&am…

Linux 目录结构

初学Linux&#xff0c;首先需要弄清Linux 标准目录结构 / root --- 启动Linux时使用的一些核心文件。如操作系统内核、引导程序Grub等。home --- 存储普通用户的个人文件 ftp --- 用户所有服务httpdsambauser1user2bin --- 系统启动时需要的执行文件&#xff08;二进制&#x…

【TypeScript】中关于 { 声明合并 } 的使用及注意事项

概念&#xff1a; 在TS中&#xff0c;如果定义了多个相同命名的函数&#xff0c;接口或者class 类&#xff0c;那么它们会自动合并成一个类型 函数的合并&#xff1a; 前面章节讲解的函数重载就是使用了定义多个函数的类型进行合并&#xff1a; function reverse(x: number):…

在家构建您的迷你聊天Chat gpt

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 什么是指令遵循模型&#xff1f; 语言模型是机器学习模型&#xff0c;可以根据句子的前一个单词预测单词概率。如果我们向模型请求下一个单词&#xff0c;并将其递减地反馈给模型以请求更多单词&#xff…

css3背景渐变

1.线性渐变 <style>.box {width: 200px;height: 200px;border: 1px solid black;float: left;margin-left: 50px;}.box1 {background-image: linear-gradient(green, yellow, red);}/* 右上 */.box2 {background-image: linear-gradient(to right top, green, yellow, re…