链表经典面试题一

《数据结构》十道链表经典面试题多种方法深度解析 《数据结构》十道链表经典面试题多种方法深度解析,配有图解深度挖掘各种细节问题,打好根基,为冲击金丹期做准备。 阅读详情

题型一:从尾到头打印链表
方法一:递归方式

void printtailtohead1(ListNode* ppHead)//从尾到头打印链表
{
     if (!ppHead)
          return;
     printtailtohead1(ppHead->pNext);
     printf("%d->", ppHead->data);
}

方法二:遍历链表
思想:定义一个指针end指向NULL,再定义一个当前节点cur指向指向链表的最后一个节点,输出最后一个节点的数据,再将cur的值赋给end,相当于end前移一个节点,再次使cur->next=end;循环结束条件是end指向了头节点。如下图所示:

void printtailtohead2(ListNode* pHead)//从尾到头打印链表
{
     ListNode* end = NULL;
     while (pHead != end)
     {
          ListNode* cur = pHead;
          while (cur->pNext != end)
          {
              cur = cur->pNext;
          }
          printf("%d->", cur->data);
          end = cur;
     }    

}

题型二:删除无头链表的非尾节点(要求不能遍历链表)

分析:这个题的思想十分简单,不能遍历链表就意味着找到要删除这个节点的前一个节点,这样就给我们的删除带来了一些困难,不过,换一个方向思考,那是不是可以将要删除的这个节点的数据用其后一个节点覆盖呢?答案是可以的,并且这个的操作十分简单,简单的代码实现如下:

void DelNodeNoHead(ListNode* pos)//删除无头链表的非尾节点
{
     assert(pos&&pos->pNext);
     ListNode* Next = pos->pNext;
     pos->pNext = Next->pNext;
     pos->data = Next->data;
     free(Next);
}

题型三:在一个无头链表前插入一个数据(要求不能遍历链表)

分析:由于不能遍历整个链表,所以就不能找到指定位置的前一个节点,所以插入也变得优点困难,但是换一中思路,如果就在当前节点后面插入一个链表,再将链表里面的数据交换,是不是就可以达到在指定位置前面插入一个节点,如下图所示:

void InsertNoHead(ListNode* pos,TypeDate x)//在指定为之前插入一个节点
{
     ListNode* NewNode = BuyNode(pos->data);
    NewNode->pNext=pos->pNext;
     pos->pNext=NewNode;
     pos->data = x;
}

测试代码如下:

testInsertNoHead()
{
     ListNode* S = NULL;//初始化链表
     ListNode* pos = NULL;
     SListPushback(&S, 2);
     SListPushback(&S, 4);
     SListPushback(&S, 6);
     SListPushback(&S, 8);
     SListPushback(&S, 10);
     SListPushback(&S, 12);
     SListPushback(&S, 14);
     SListPrint(S);
     pos = Find(S, 8);
     InsertNoHead(pos,7);
     SListPrint(S);
}

题型四:单链表实现约瑟夫环:
分析:首先我们应该了解什么事约瑟夫环:
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后 结果+1即为原问题的解。
在这里我们返回剩的最后一个人,看谁是最后的幸运者:
解决约瑟夫环的问题,首先要确定要思路,数到k的人要出列,那也就是说删除第k个节点,然后再继续循环,又从0开始数数,数到k,那么这个人就出列,也就是删除该位置的节点,循环结束条件是:当当前节点指向自己,也就能意味着只剩下了一个人了,返回这个人的值,看和自己推倒的结果是否是一致的。(为了构成环,我们需要将尾节点的next指向头节点),根据这个思路我们就可以很容易写出代码了,代码如下:

ListNode* JosephCycle(ListNode* pHead, int k)//约瑟夫环
{
     ListNode* tail = pHead;
     ListNode* cur = pHead;
     if (pHead==NULL)
          return NULL;
     //构成环
     while (tail->pNext)
     {
          tail = tail->pNext;
     }
     tail->pNext = pHead;
     while (cur!=cur->pNext)
     {
          ListNode* NextNode = NULL;
          int count = k;
          while (--count)//循环count-1次
          {
              cur = cur->pNext;
          }
          NextNode = cur->pNext;
          cur->data = NextNode->data;
          cur->pNext = NextNode->pNext;
          free(NextNode);
     }
     return cur;
}

测试代码如下:

testJosephCycle()
{
     ListNode* S = NULL;//初始化链表
     ListNode* pos = NULL;
     SListPushback(&S, 1);
     SListPushback(&S, 2);
     SListPushback(&S, 3);
     SListPushback(&S, 4);
     SListPushback(&S, 5);
     SListPushback(&S, 6);
     SListPushback(&S, 7);
     SListPushback(&S, 8);
     pos = JosephCycle(S, 5);
     printf("幸存者是:%d\n", pos->data);
}

题型五:逆置/反转单链表

方法一:迭代法,从头到尾改变单链表的指向,将NULL置为新的头节点,再将原先的头节点置为NULL;详细过程如图:

void Listreservalone(ListNode** ppHead)//逆置链表,迭代法
{
     ListNode* Node1=*ppHead;
     ListNode* Node2 = Node1->pNext;
     ListNode* Node3 = Node2->pNext;
     if ((*ppHead) == NULL||(*ppHead)->pNext==NULL)
     {
          return *ppHead;
     }
     while (Node2 != NULL)
     {
          Node2->pNext = Node1;
          Node1 = Node2;
          Node2 = Node3;
          if (Node3 != NULL)
          {
              Node3 = Node3->pNext;
          }
     }
     (*ppHead)->pNext = NULL;
     (*ppHead) = Node1;
}

方法二:头删头插法,设置一个指针指向当前链表的头节点,用一个临时变量来保存当前节点。再创建一个新的头节点,将临时变量头插给给个新的头节点。在循环条件内,当前节点持续后移。这样就可以将这个链表逆置过来,这个链表的头节点就是新建的头节点。

ListNode* Listreservaltwo(ListNode* pHead)//逆置链表,头删头插的方法
{
     ListNode* NewHead=NULL;
     ListNode* tmp;
     ListNode* cur=pHead;
     while (cur)
     {
          tmp = cur;
          cur = cur->pNext;
          tmp->pNext = NewHead;//头插
          NewHead = tmp;
     }
     return NewHead;
}

测试代码如下:

testListreservaltwo()
{
     ListNode* S = NULL;//初始化链表
     ListNode* head = NULL;
     SListPushback(&S, 1);
     SListPushback(&S, 2);
     SListPushback(&S, 3);
     SListPushback(&S, 4);
     SListPushback(&S, 5);
     SListPushback(&S, 6);
     SListPushback(&S, 7);
     SListPushback(&S, 8);
     SListPrint(S);
     head=Listreservaltwo(S);
     SListPrint(head);
}

题型六:单链表的冒泡排序:

分析:链表的冒泡排序和普通排序并没有很大区别,思想都是一样的。我们需要创建三个指针,两个指针用来遍历整个链表,一个指针用来控制循环结束条件。,如下图所示 :

void Bubblesort(ListNode* pHead)//单链表的冒泡排序
{
     ListNode* cur;
     ListNode* Next;
     ListNode* tail = NULL;
     int flag = 0;
     while (tail != pHead->pNext)
     {
          cur = pHead;
          Next = pHead->pNext;
          while (Next != tail)
          {
              if (cur->data > Next->data)
              {
                   int tmp = cur->data;
                   cur->data = Next->data;
                   Next->data = tmp;
                   flag = 1;
              }
              cur = cur->pNext;
              Next = Next->pNext;
          }
          tail = cur;//尾每次前移动一位
          if (flag == 0)//表示一次都没有交换,则 本身就是有序的,就不需要遍历了
          {
              break;
          }
     }
}
测试代码如下:
testBubblesort()
{
     ListNode* S = NULL;//初始化链表
     SListPushback(&S, 1);
     SListPushback(&S, 22);
     SListPushback(&S, 3);
     SListPushback(&S, 9);
     SListPushback(&S, 10);
     SListPushback(&S, 6);
     SListPushback(&S, 7);
     SListPushback(&S, 18);
     Bubblesort(S);
     SListPrint(S);
}
把数字化转型真正落到组织里:读懂 SAP 的 OCM 六维框架 摘要: SAP的变革管理框架(OCM)强调数字化转型不仅是技术任务,更需关注组织与人的适应性。OCM包含六大维度:变革战略(明确方向与风险)、变革领导力(统一关键管理者行动)、变革沟通(分层传递信息)、变革实现(细化岗位级影响)、变革赋能(按角色设计培训)和变革有效性(持续评估)。该框架贯穿项目全周期,尤其在云项目中,需从早期规划变革策略,避免后期高代价调整。OCM的核心是将系统设计转化为组织语言,确保业务真正采纳新方式运作。 阅读详情

相关推荐

VMware Workstation Pro 16 安装 Ubuntu 20.04

VMware Workstation Pro 16 安装 ubuntu 20.04目录环境VMware Workstation下载Ubuntu 20.04下载安装过程 目录 环境 Windows 10 Workstation 16 Pro for Windows Ubuntu 20.04 LTS 64位 desktop版本 VMware Workstation下载 链接: https://www.vmware.com/products/workstation-pro/workstation-pro-eval

qq_45642410的博客 1万+

10道经典链表面试题

目录 1.删除链表中等于给定值val的所有节点 2.反转一个单链表 3.给定一个带有头结点head的非空单链表,返回链表的中间结点。如果有两个中间结点,则 返回第二个中间结点 4.输入一个链表,输出该链表中倒数第k个结点 5.将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所 有节点组成的 6. 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的 结点之前 7. 链表的回文结构 8. 输入两个链表,找出它们.........

xaiobit_hl的博客 4287

Research Proposal:自动驾驶 行人运动预测

Research Proposal about Pedestrian/Cyclist Motion Prediction for Self-Driving Vehicles   If I can be provided with the opportunity to conduct PhD research in pedestrian/cyclist motion prediction for...

Poetry Wanderer的博客 3086

链表常见面试题( 建议收藏!!)

链表面试题????1.删除链表中等于给定值 val 的所有节点2.二级目录3.三级目录 1.删除链表中等于给定值 val 的所有节点 题目: 题目链接: https://leetcode-cn.com/problems/remove-linked-list-elements/. 思考: 用tmp记录当前节点,若tmp 的下一个节点不为空且下一个节点的节点值等于给定的 val,则需要删除tmp的下一个节点 2.二级目录 3.三级目录 ...

一朵花花 4624

信创改造实战:SpringBoot项目迁移到宝兰德BES 9.5.5的完整避坑指南(附依赖与web.xml配置)

本文详细介绍了将SpringBoot项目迁移到宝兰德BES 9.5.5的完整流程,包括依赖改造、web.xml配置降级等关键步骤。通过实战案例和避坑指南,帮助开发者高效完成国产中间件适配,确保项目平稳运行。特别针对Tomcat依赖排除和BES适配器选择提供了专业建议。

weixin_30689307的博客 735

SoC 内的 CPU、GPU、DSP、NPU 协同执行结构图解析:多异构协同的最新实战体系

随着移动端 AI 能力迅速演进,SoC(System on Chip)内部的多种异构计算单元(CPU、GPU、DSP、NPU)之间的协同执行能力成为衡量芯片智能算力的关键指标。本文基于截至 2025 年 5 月最新主流国产芯片(如海思昇腾、地平线旭日、联发科天玑、高通骁龙 8 Gen 系、寒武纪思元等)在实际落地应用中的公开结构与技术资料,深入解析 CPU-GPU-DSP-NPU 协同执行的体系结构、执行路径与调度逻辑。文章结合 Android NNAPI、Vulkan Compute、自定义调度器等工程实

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 8707

【数据结构】10道经典面试题目带你玩转链表

10道关于链表的经典面试题目:包含移除链表元素,反转链表,链表的中间结点,链表中倒数第K个结点,合并两个有序链表,链表分割,链表的回文结构,相交链表,环形链表,环形链表找入环点等题目的解题思路图解及完整解题代码.

C/C++领域,数据结构,linux,MySQl学习者 2379

网表导入virtuoso后发现pg pin忘记connect_pg_net/globalNetConnect怎么办?

数模混合项目中经常需要一些需要到virtuoso去连接的线,比如IO上的pg和一些信号线,除了在pr工作中设置skip route之外还需要做好net的赋值,告诉工具虽然我没在物理上有连接,但是实际上应该连什么net,这部分提现在网表里。在Default Net Name中也填写net name,因为这个net需要做global操作,即在顶层定义这个net,所以需要在net name后加个!打开schematic,删除指定cell pin所接net的label。

m0_61544122的博客 967

【数据结构】7道经典链表面试题

题目描述: 给你一个链表的头节点head,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数pos来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos不作为参数进行传递。仅仅是为了标识链表的实际情况。 如果链表中存在环,则返回true。 否则,返回false。 题目描述: 给定一个链表的头节点 head,返回链表开始入环的第一个节点。如果链表无环,则返回null

2302_81312180的博客 1882

VisionPro 机器视觉案例 之 彩色保险丝个数统计

CogColorSegmenterTool CogColorMatchTool

机器视觉李小白的博客 2352

西门子S7-1200PLC控制步进电机的组态编程和具体步骤

西门子S7-1200PLC控制步进电机的组态编程和具体步骤 硬件准备: 1) 一个S7-1214C DC/DC/DC,订货号:6ES7 214-1AG40-0XB0 2) 一个86系的步进电机+相应的驱动器 3) 一个20A的西门子24V电源(步进驱动器及plc电源) 4) Portal V15版本 组态及编程: 1) 创建一个验证项目,添加cpu( S7-1214C),双击“工艺对象”,选择“运动控制”的TO_PositioningAxis V6.0版本,如下图所示: 2) “确定”后,系统自动生成名

Robot_PLC_HMI_Automation 1万+

有关链表的经典面试题 (一)

逆置/反转单链表。  单链表排序(冒泡排序&快速排序)。  合并两个有序链表,合并后依然有序。 查找单链表的中间节点,要求只能遍历一

gunqu_d的博客 403

Python全栈入门到实战【基础篇 04】核心基础:变量与4种基础数据类型(int/float/str/bool)

本文介绍了Python编程中的变量和四种基础数据类型,作为后续所有语法的入门前提。变量是数据的“容器”,解决数据复用问题,而数据类型决定数据能进行的操作。文章详细讲解了变量的定义语法、命名规则(强制语法和推荐风格)、赋值与修改原理,并通过实操示例展示其应用场景。正确使用变量可以提升代码复用性、简化修改并增强可读性,是编程效率的核心原则。掌握这些基础知识能避免90%的新手语法错误,为学习更复杂的Python语法打下坚实基础。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 4307

链表经典面试题(一)

反转链表

m0_73111651的博客 204

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【经典算法面试题一】反转链表的两种解决方法

类似题目:反转一个单链表 输入:1->2->3->4->5 输出:5->4->3->2->1 解法1:迭代 重复某一过程,每一次处理结果作为下一次的初始值,这些初始值类似于状态、每次处理都会改变状态、直至到达最终状态。 先定义三个变量 prev:保存当前节点的上一个节点;将当前节点的next指向上一个节点 curr:保存当前节点; next:提前保存当前节点的下一个节点 从前往后遍历步骤: 1.将当前节点赋值给curr,curr = head;初始化pre

编程菜鸟的分享与学习 505

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

经典的面试题:链表的相交与环问题 (一)

1、 给出两个单向链表的头指针pHead1和pHead2,判断这两个链表是否相交。假设两个链表均不带环。 示意图如下:   如果两个链表相交于某一节点,那么在这个相交节点之后的所有节点都是两个链表所共有的。也就是说,如果两个链表相交,那么最后一个节点肯定是共有的。先遍历第一个链表,记住最后一个节点,然后遍历第二个链表,到最后一个节点时和第一个链表的最后一个节点做比较,如果相同,则相交,否

miao6664659的专栏 935

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

【单链表经典面试题解析一】从尾到头打印单链表

从尾到头打印单链表,我们可以

sofia_m的博客 572

面试题: 怎么将单链表反转?

package com.example.file; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ReverseListTest { public static class Node{ int val; Node next; Node(int x) { ...

Dream_it_possible!的博客 494

【剑指Offer学习】【所有面试题汇总】

剑指Offer学习   剑指Offer这本书已经学习完了,从中也学习到了不少的东西,现在做一个总的目录,供自已和大家一起参考,学如逆水行舟,不进则退。只有不断地学习才能跟上时候,跟得上技术的潮流! 所有代码下载【https://github.com/Wang-Jun-Chao/coding-interviews】 目录 第01-10题 【剑

Together_CZ的博客 5万+

O(N lgK) 时间内合并K个有序链表

问题: 在O(N lgK) 时间内合并K个有序链表, 这里N指的是K个链表中所有的元素个数。 分析: 这是一道非常经典的面试题,在很多大公司的面试题中,此题频繁出现。这题也是算法导论的作业题。 这题的思路如下: 1) 在每一个链表中取出第一个值,然后把它们放在一个大小为K的数组里,然后把这个数组当成heap,然后把该堆建成最小堆。此步骤的时间复杂度为O(K) 2 )取出堆中的最小值(也

Yuwen's Hero 4417

链表知识总结

**插入/删除** | **低**(除非在尾部操作),需要移动元素,平均时间复杂度**O(n)** | **高**,只需修改指针,时间复杂度**O(1)**(前提是已定位到结点)|| **访问效率** | **高**,通过索引直接访问,时间复杂度**O(1)** | **低**,需要从头或尾遍历,平均时间复杂度**O(n)** |数据元素的逻辑顺序是通过链表中的**指针链接次序**实现。* 如果你的操作是“**改多查少**”,或者需要频繁实现栈、队列、双向队列等结构,请选择`LinkedList`。

2503_92635477的博客 926

链表好题-多种实现

其实思路是一样的,他那边的合并链表,我们主要是利用p = nxt这一条语句做到的(好好体会),反转链表是通过栈来翻转的,寻找中点是通过。这种方法非常经典,一道题顶三道题,其中各种边界条件也令人很头疼。找到的,同样要注意边界条件。这道题难度还是比较高的。这道题非常经典,很多大厂都作为面试题。方法一:寻找中点+翻转链表+合并链表。

WaNgmingming12的博客 428

[吊打面试官-力扣经典题]力扣- 反转链表206 迭代法[图解] 简单详细,[画解LC]

经典题, 反转链表

QianZe013的博客 145

线性表——顺序表与单链表学习小结

线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。 顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采...

weixin_33716557的博客 643

剑指offer - 21.调整数组的顺序使奇数排在偶数前|22.链表中倒数第k个节点

面试题21.调整数组的顺序使奇数排在偶数前 题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。 解题思路: 新建一个数组,当遇到是奇数的时候Push到新数组里,然后再循环一次当遇到偶数时Push到新数组里,最后将新数组数据覆盖老数组,复杂度O(n) method: ...

Qzx9059的博客 294

单向链表的逆置问题

C++实现单向链表的逆置,哑结点位置不变。

阿正的梦工坊 747
上一篇: 链表之双向有头循环链表
下一篇: 链表经典面试题二
ffsiwei
博客等级 码龄9年 72粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值