实现链表反转

简介: 实现链表反转

前言


有一个链表,如何将其反转并获取反转后的链表头节点?本文将分享一种解决方案,欢迎各位感兴趣的开发者阅读本文。


思路分析


经过数据结构基础的学习,我们知道链表中每个节点都会有一个指针,用于指向它的下一个节点,那么,我们只需要从链表头部开始遍历,逐一修改它的指针指向至其上一个节点,即可完成链表的反转。


这个思路的难点在于如何调整指针的指向,我们可以借助3个指针来完成这个操作,如下所示:


  • p1、p3分别是p2指针的上、下一个节点(默认指向null)
  • 如果p2指针指向的节点不为null
  • 获取p2指针指向的下一个节点,将其保存至p3
  • 如果p3的值为null,则表示链表已经反转完毕,用一个变量存储p2的值
  • 修改p2指针的指向至p1,修改p1的值为p2,修改p2的值为p3


640.jpg

                               IMG_12BA2C91C60A-1


实现代码


通过上面的分析,我们分析出了可以用三指针来解决问题的思路,接下来,我们来看下代码实现。


首先,设计一个名为ReverseLinkedList的类:


  • 内部有2个私有变量
  • pPrev p1指针
  • pNode p2指针
  • 构造方法接受1个参数:链表头节点
  • 对参数进行校验
  • 初始化p2指针指向为链表头节点,p1指针的指向为null


export class ReverseLinkedList {
  // p1指针
  private pPrev: ListNode | null;
  // p2指针
  private pNode: ListNode | null;
  constructor(listHead: ListNode) {
    if (listHead == null) {
      throw new Error("链表头节点不能为空");
    }
    this.pNode = listHead;
    this.pPrev = null;
  } 
}


上述代码中,我们用了一个自定义类型ListNode,它描述了一个链表的节点应该包含哪些属性,对此感兴趣的开发者请移步我的另一篇文章:链表与变相链表的实现。

紧接着,实现链表反转函数:


  • 声明一个变量用于存储反转后的链表头指针
  • 移动p2指针,开始遍历链表
  • 存储p2指针的下一个节点至p3
  • 判断p2指针是否为走到链表末尾,条件成立就修改存储p2节点至反转后的链表头指针变量
  • 修改p2指针的指向至p1,修改p1的值为p2,修改p2的值为p3
  • p2指针指向null,返回得到的链表头节点


reverseList(): ListNode | null {
    // 反转后的链表头指针
    let pReversedHead: ListNode | null = null;
    while (this.pNode != null) {
      // p3指针
      const pNext = this.pNode.next;
      if (pNext == null) {
        pReversedHead = this.pNode;
      }
      this.pNode.next = this.pPrev;
      this.pPrev = this.pNode;
      this.pNode = pNext;
    }
    return pReversedHead;
  }


完整代码请移步👉:ReverseLinkedList.ts


测试用例


接下来,我们将前言中的例子代入上个章节所实现的函数中,验证下它能否得出正确的结果。


const linkedList = new LinkedList();
linkedList.push(1);
linkedList.push(3);
linkedList.push(8);
linkedList.push(9);
linkedList.push(12);
linkedList.push(18);
const reverseLinkedList = new ReverseLinkedList(linkedList.getHead());
const result = reverseLinkedList.reverseList();
console.log("反转后的链表头节点为", result);


运行结果如下所示,成功的解决了文章前言中所讲的问题。


640.png

                                 image-20220615221918607


完整代码请移步👉:reverseLinkedList-test.ts


注意:上述代码中用到的LinkedList是自定义的一个类,它实现了链表这个数据结构,对其原理感兴趣的开发者请移步我的另一篇文章👉:链表与变相链表的实现。


示例代码


本文所列举的代码,其完整版请移步👇:


  • ReverseLinkedList.ts
  • reverseLinkedList-test.ts


写在最后


至此,文章就分享完毕了。


我是神奇的程序员,一位前端开发工程师。


如果你对我感兴趣,请移步我的个人网站,进一步了解。

  • 公众号无法外链,如果文中有链接,可点击下方阅读原文查看😊
相关文章
|
开发框架 iOS开发
iOS开发之AVKit框架使用
iOS开发之AVKit框架使用
1359 0
iOS开发之AVKit框架使用
|
3月前
|
Web App开发 人工智能 JavaScript
199 元找人定制 Codex 主题?未曾设想的赚钱道路。。我免费教你怎么做
Codex 定制主题皮肤保姆级教程,借助 GitHub 开源项目,根本不需要花钱!
416 0
|
5月前
|
人工智能 机器人 API
Hermes Agent是什么?本地+云端+Docker全平台部署与阿里云百炼接入实操手册
Hermes Agent是由Nous Research开发的开源自主AI智能体框架,遵循MIT开源协议,核心定位是打造具备持久记忆、自我进化、多工具调用与跨平台接入能力的“数字员工”。它并非简单的聊天机器人,而是能自主规划任务、沉淀技能、跨会话召回记忆的智能执行体,真正实现“越用越聪明”。
738 5
|
5月前
|
数据采集 人工智能 监控
办公Agent + 企业知识库:自动生成季度报告与竞品分析文档
本文揭秘一款专为企业打造的办公Agent:它能自动连通CRM、飞书、竞品官网等知识源,按模板生成季度复盘与竞品分析初稿,引用皆可溯源。实测报告撰写从12小时缩至3分钟,人工仅需微调。不吹“全能”,只解决找资料慢、信息散、更新滞三大痛点。(239字)
418 4
|
5月前
|
人工智能 自动驾驶 前端开发
中国 AI 产业媒体与内容生态图谱:刷新 AI 认知应该关注谁?(订阅推荐)
每天打开手机,AI 新闻能刷出几百条。大模型发布、融资消息、开源项目、政策文件、大厂动态,信息量已经远远超出任何个人的处理能力。
1309 0
|
5月前
|
JSON 监控 API
V4-Flash 轻量化模型接入,​D​М‌X​Α‌РΙ 优化边缘端部署延迟
V4-Flash是DeepSeek于2026年推出的轻量化MoE大模型,支持1M上下文、384K输出与双模式推理,兼顾强能力与低延迟;结合DMXAPI标准化接入,可实现统一鉴权、流控、可观测与多模型路由,显著优化边缘部署效率与生产稳定性。(239字)
|
7月前
|
编译器 C语言
C语言「数组名豁免规则」:3个绝不退化为指针的铁则
C语言中“数组名即指针”是常见误读。实则数组名仅在3种例外下不隐式转为指针:作sizeof操作数、取地址&、字符串字面量初始化。这三处保留数组类型与大小,是理解数组/指针本质区别的关键。(239字)
377 9
|
网络协议 测试技术 网络架构
网络性能测试工具iperf详细使用图文教程zz
http://blog.csdn.net/zm_21/article/details/25868589 Iperf的主要功能如下: TCP 测量网络带宽 报告MSS/MTU值的大小和观测值 支持TCP窗口值通过套接字缓冲 当P线程或Win32线程可用时,支持多线程。
4034 0
|
JavaScript
《SAP后勤模块实施攻略—SAP在生产、采购、销售、物流中的应用》——第3章 MRP简介 3.1 MRP运行的简要说明
本节书摘来自华章计算机《SAP后勤模块实施攻略—SAP在生产、采购、销售、物流中的应用》一书中的第3章,第3.1节,作者 乐立骏,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
5270 0

热门文章

最新文章