C++面试宝典第4题:合并链表

题目

        有一个链表,其节点声明如下:

struct TNode
{int nData;struct TNode *pNext;TNode(int x) : nData(x), pNext(NULL) {}
};

        现给定两个按升序排列的单链表pA和pB,请编写一个函数,实现这两个单链表的合并。合并后,仍然按升序进行排列。比如:单链表pA为1->3->5->6->8,单链表pB为2->3->7,则合并后返回的链表为1->2->3->3->5->6->7->8。函数的声明如下:

          TNode *MergeList(TNode *pA, TNode *pB);

解析

        这道题主要考察应聘者对链表等数据结构的理解能力,在面试中比较常见。一般有两种解法:一种是使用递归函数来实现,另一种是使用链表遍历来实现。

        先来看第一种解法,使用递归函数来实现。当链表pA为NULL时,直接返回链表pB即可。当链表pB为NULL时,直接返回链表pA即可。当链表pA和pB均不为NULL时,则比较链表首部的元素,若pA->nData小于pB->nData,则返回pA,并让pA->pNext指向递归函数MergeList(pA->pNext, pB)的返回值。下面,我们给出了这道题的示例代码。

#include<iostream>
using namespace std;struct TNode
{int nData;struct TNode *pNext;TNode(int x) : nData(x), pNext(NULL) {}
};// 插入新节点到链表尾部
TNode *AppendNode(TNode *pTail, int nData)
{  TNode *pNodeNew = new TNode(nData);pTail->pNext = pNodeNew;return pNodeNew;
}// 打印链表
void PrintList(TNode *pNode)
{while (pNode != NULL){cout << pNode->nData;pNode = pNode->pNext;if (pNode != NULL){cout << "->";}else{cout << endl;}}
}// 合并两个链表
TNode *MergeList(TNode *pA, TNode *pB)
{  if (pA == NULL){return pB;}if (pB == NULL){return pA;}if (pA->nData < pB->nData){pA->pNext = MergeList(pA->pNext, pB);return pA;}else{pB->pNext = MergeList(pA, pB->pNext);return pB;}
}  int main()
{TNode *pA = new TNode(1);TNode *pTail = AppendNode(pA, 3);pTail = AppendNode(pTail, 5);pTail = AppendNode(pTail, 6);pTail = AppendNode(pTail, 8);// 输出:1->3->5->6->8PrintList(pA);TNode *pB = new TNode(2);pTail = AppendNode(pB, 3);pTail = AppendNode(pTail, 7);// 输出:2->3->7PrintList(pB);TNode *pResult = MergeList(pA, pB);// 输出:1->2->3->3->5->6->7->8PrintList(pResult);return 0;
}

        当然,递归函数也有其缺点:当链表中的元素较多,递归的层级较多时,可能会导致堆栈溢出。

        接下来,我们来看第二种解法,使用链表遍历来实现。首先,当链表pA和pB其中一个为NULL时,直接返回另一个链表即可。接下来,我们创建了一个新的临时节点,作为新链表的头和尾,并遍历链表pA和pB。在遍历过程中,如果pA->nData小于pB->nData,则将pA作为新链表尾部的下一个节点,并遍历新链表尾部和pA的下一个节点;如果pA->nData不小于pB->nData,则将pB作为新链表尾部的下一个节点,并遍历新链表尾部和pB的下一个节点。循环遍历完成后,由于链表pA和pB不一样长,因此,需要检查链表pA和pB是否为NULL。若不为NULL,则将对应链表放到新链表尾部。最后,我们返回了新建节点的下一个节点作为合并后的链表首节点,并删除了新建的临时节点。具体实现,可参考如下的示例代码。

#include<iostream>
using namespace std;struct TNode
{int nData;struct TNode *pNext;TNode(int x) : nData(x), pNext(NULL) {}
};// 插入新节点到链表尾部
TNode *AppendNode(TNode *pTail, int nData)
{  TNode *pNodeNew = new TNode(nData);pTail->pNext = pNodeNew;return pNodeNew;
}// 打印链表
void PrintList(TNode *pNode)
{while (pNode != NULL){cout << pNode->nData;pNode = pNode->pNext;if (pNode != NULL){cout << "->";}else{cout << endl;}}
}// 合并两个链表
TNode *MergeList(TNode *pA, TNode *pB)
{if (pA == NULL){return pB;}if (pB == NULL){return pA;}TNode *pResult = new TNode(-1);TNode *pTail = pResult;while (pA && pB){if (pA->nData < pB->nData){pTail->pNext = pA;pTail = pTail->pNext;pA = pA->pNext;} else{pTail->pNext = pB;pTail = pTail->pNext;pB = pB->pNext;}}if (pA){pTail->pNext = pA;}if (pB){pTail->pNext = pB;}TNode *pTemp = pResult;pResult = pResult->pNext;delete pTemp;return pResult;
}int main()
{TNode *pA = new TNode(1);TNode *pTail = AppendNode(pA, 3);pTail = AppendNode(pTail, 5);pTail = AppendNode(pTail, 6);pTail = AppendNode(pTail, 8);// 输出:1->3->5->6->8PrintList(pA);TNode *pB = new TNode(2);pTail = AppendNode(pB, 3);pTail = AppendNode(pTail, 7);// 输出:2->3->7PrintList(pB);TNode *pResult = MergeList(pA, pB);// 输出:1->2->3->3->5->6->7->8PrintList(pResult);return 0;
}

总结

        链表是一种常见的数据结构,它通过指针链接一系列的节点。通过这道题,我们学习了链表的数据结构,以及链表合并的操作。

        另外,我们还为你留了一些课后的拓展作业,快来试一试吧!

        1、给定一个单向链表,判断链表中是否有环。

        2、给定一个单向链表的头节点,写一个函数将其反转。

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

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

相关文章

scheduleatfixedrate详解

scheduleatfixedrate详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在Java开发中&#xff0c;我们常常需要执行定时任务&#xff0c;并且需要保证任务按照一定…

使用Java实现基数排序算法

文章目录 基数排序算法 基数排序算法 &#xff08;1&#xff09;基本思想&#xff1a;将整数按位数切割成不同的数字&#xff0c;然后按每个位数分别比较。 &#xff08;2&#xff09;排序过程&#xff1a;将所有待比较数值&#xff08;正整数&#xff09;统一为同样的数位长…

Vuex快速上手

一、Vuex 概述 目标&#xff1a;明确Vuex是什么&#xff0c;应用场景以及优势 1.是什么 Vuex 是一个 Vue 的 状态管理工具&#xff0c;状态就是数据。 大白话&#xff1a;Vuex 是一个插件&#xff0c;可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。例如&#xff1a;购…

VSCode SSH登录服务器 提示XHR failed

设置->搜索“代理” 把图中的√去掉 重启 即可

OVS主线流程

OVS是open virtual switch的简称&#xff0c;是现在广泛使用的软件实现的虚拟网络交换机。 各大云厂商普遍使用OVS来实现自身的虚拟网络&#xff0c;各厂商会根据自身需要加以修改使之符合自身需求&#xff0c;DPU中也使用OVS来实现流表的offload。OVS中的流表基于多级结构&am…

变相增大BatchSize——梯度累积

常规训练方式 for x,y in train_loader:pred model(x)loss criterion(pred, label)# 反向传播loss.backward()# 根据新的梯度更新网络参数optimizer.step()# 清空以往梯度&#xff0c;通过下面反向传播重新计算梯度optimizer.zero_grad() pytorch每次forward完都会得到一个…

tidb安装 centos7单机集群

安装 [rootlocalhost ~]# curl --proto https --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh [rootlocalhost ~]# source .bash_profile [rootlocalhost ~]# which tiup [rootlocalhost ~]# tiup playground v6.1.0 --db 2 --pd 3 --kv 3 --host 192.168.1…

按这个套路写的年底工作总结,运维人能少背多少锅?

在职场中&#xff0c;年终工作总结是一项重要的任务&#xff0c;不仅有助于回顾过去一年的工作成果&#xff0c;也为未来设定新的目标提供了参考。在进行年终工作总结的过程中&#xff0c;合理的工作汇报是至关重要的一环。 一、汇报需要坚守的4个法则 01.线索必须单一 观点&am…

js实现元素可拖拽方法

业务需要&#xff1a;Vueelement plus实现对弹框进行拖拽&#xff0c;并可拖拽到显示页面的外面&#xff0c;而element提供的拖拽只能在当前页面不可超出。所以手写了拖拽方法。 实现效果 对元素进行拖拽 拖拽方法 function dragElement(ele) {ele.addEventListener("mous…

SQL自学通之函数 :对数据的进一步处理

目录 一、目标 二、汇总函数 COUNT SUM AVG MAX MIN VARIANCE STDDEV 三、日期/时间函数 ADD_MONTHS LAST_DAY MONTHS_BETWEEN NEW_TIME NEXT_DAY SYSDATE 四、数学函数 ABS CEIL 和FLOOR COS、 COSH 、SIN 、SINH、 TAN、 TANH EXP LN and LOG MOD POW…

【SpringBoot教程】SpringBoot 实现前后端分离的跨域访问(Nginx)

作者简介&#xff1a;大家好&#xff0c;我是撸代码的羊驼&#xff0c;前阿里巴巴架构师&#xff0c;现某互联网公司CTO 联系v&#xff1a;sulny_ann&#xff08;17362204968&#xff09;&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗…

Mybatis之核心配置文件详解、默认类型别名、Mybatis获取参数值的两种方式

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

arm-none-eabi-gcc not find

解决办法&#xff1a;安装&#xff1a;gcc-arm-none-eabi sudo apt install gcc-arm-none-eabi; 如果上边解决问题了就不用管了&#xff0c;如果解决不了&#xff0c;加上下面这句试试运气&#xff1a; $ sudo apt-get install lsb-core看吧方正我是运气还不错&#xff0c;感…

leetcode周赛375 - 12 - 10

比赛地址 : 竞赛 - 力扣 (LeetCode) t1 : 直接暴力即可 class Solution { public:int countTestedDevices(vector<int>& b) {int n b.size();int ans 0;for(int i0;i<n;i){if(b[i]>0){ans ;for(int ji1;j<n;j){b[j] max(b[j]-1,0);}}}return ans;} };…

SSL 数字证书的一些细节

参考&#xff1a;TLS/SSL 协议详解(6) SSL 数字证书的一些细节1 证书验证 地址&#xff1a;https://wonderful.blog.csdn.net/article/details/77867063 参考&#xff1a;TLS/SSL协议详解 (7) SSL 数字证书的一些细节2 地址&#xff1a;https://wonderful.blog.csdn.net/articl…

Python学习笔记-类

1 定义类 类是函数的集合&#xff0c;class来定义类 pass并没有实际含义&#xff0c;只是为了代码能执行通过&#xff0c;不报错而已&#xff0c;相当于在代码种占一个位置&#xff0c;后续完善 类是对象的加工厂 2.创建对象 carCar()即是创建对象的过程 3、类的成员 3.1 实例…

福德植保无人机:绿色农业的新篇章

今天&#xff0c;我们荣幸地向您介绍福德植保无人机&#xff0c;一种改变传统农业种植方式&#xff0c;引领绿色农业的新科技产品。福德植保无人机以其高效、环保、安全的特点&#xff0c;正逐渐成为植保行业的新宠。福德植保无人机是一种搭载了高性能发动机和精确喷洒系统的飞…

代码随想录算法训练营第四十六天 _ 动态规划_背包问题总结。

学习目标&#xff1a; 动态规划五部曲&#xff1a; ① 确定dp[i]的含义 ② 求递推公式 ③ dp数组如何初始化 ④ 确定遍历顺序 ⑤ 打印递归数组 ---- 调试 引用自代码随想录&#xff01; 本文大多数内容引用自代码随想录 60天训练营打卡计划&#xff01; 学习内容&#xff1a; …

POJ - 2528 Mayor‘s posters

本题注意离散化的时候可能会出现区间串联情况&#xff0c;比如 [1,10] [5,10] [1,4] 和 [1,10] [6,10] [1,4] 直接离散化的话两者一样&#xff0c;但是实际上是不一样的 解决办法是你在相邻的差不是1的数对中再插一个数就好了 离线区间染色 查询根节点 #include<iostrea…

ASPICE-汽车软件开发能力评级

Automotive SPICE&#xff08;简称A-SPICE 或 ASPICE&#xff09;&#xff0c;全称是“Automotive Software Process Improvement and Capacity dEtermination”&#xff0c;即“汽车软件过程改进及能力评定”模型框架。 常被用于评估一家汽车软件供应商的软件开发能力&#x…