当我们在聊到链表反转的时候,一定说的都是单链表,双链表本身就具有前驱指针 Prev 和后续指针 next,无需进行翻转。

单链表反转,反转后的效果如下:

看起来很简单,只需要将单链表所有结点的 next 指向,指向它的前驱节点即可。引入一个栈结构,就可以实现。

栈实现的链表反转

在原本链表的数据结构之外,引入一个栈(数组也可),将单链表循环遍历,将所有结点入栈,最后再从栈中循环出栈,继续出栈的顺序,得到的就是反转后的单链表。

但是这样实现,有一个问题,它会额外消耗一个栈的内存空间,此时空间复杂度就变成了 O(n)。并且,栈会遇到的问题,使用此种方式都会遇到,例如栈的深度问题。

空间复杂度为 O(1) 单链表反转

在排序算法中,有一个概念叫原地排序,指的是不需要引入额外的存储空间,在原数据结构的基础上进行排序。这种排序算法的空间复杂度是 O(1)。例如我们常见的冒泡排序、插入排序都是原地排序算法。

这里,我们也可以在原单链表的数据结构上,进行单链表反转。

原地单链表反转,是一种很基础的算法,但是有一些在面试中遇到这道题,思路不清晰时,一时半会也写不出来。

容易出错的点在于,指针丢失。在转换结点指针的时候,所需结点和指针反转顺序,都很重要,一不小心,就会丢掉原本的后续指针 next,导致链表断裂。

在上一篇文章中,带单链表时间复杂度为 O(1) 的结点删除法中,介绍到,删除单链表的时候,需要知道前后三个结点。在单链表翻转的时候,也是这样。

当我们要对一个结点进行指针翻转的时候,我们也需要知道三个结点。

  • 待翻转的结点。
  • 待反转结点的前驱结点 prev。
  • 待反转结点的后续结点 next。

说了那么多,直接上代码。

static class Node { int data; Node next; Node(int data){ this.data = data; }}static Node reverseByLoop(Node head) { if (head == null || head.next == null){ return head; } Node preNode = null; Node nextNode = null; while (head != null){ nextNode = head.next; head.next = preNode; preNode = head; head = nextNode; } return preNode;}

链表翻转的所有逻辑,都在 reverseByLoop() 方法中,此处以头结点为参数,反转之后返回值为反转后的单链表头结点。

有兴趣最好自己在 IDE 里敲一遍,加深印象。

递归实现单链表翻转

单链表翻转,还可以通过递归来实现,但是这里不推荐使用,大家了解一下就好了。

递归还是在借助函数调用栈的思想,其实本质上也是一个栈。没什么好说的,直接上代码。

static Node reverseByRecursion(Node head){ if(head == null || head.next == null){ return head; } Node newHead = reverseByRecursion(head.next); head.next.next = head; head.next = null; return newHead;}

小结时刻

到这里,单链表反转的内容,都介绍完了,学算法还是要考虑多写多练,推荐大家在 IDE 中,自己手动敲一遍,加深印象。

本文对你有帮助吗?留言、点赞、转发是最大的支持,谢谢!


在头条号私信我。我会送你一些我整理的学习资料,包含:Android反编译、算法、设计模式、虚拟机、Linux、Kotlin、Python、爬虫、Web项目源码。

c语言双链表排序交换节点_图解:单链表翻转的三种方式!相关推荐

  1. 单链表的基本操作_数据结构-单链表的基本操作

    typedef int ElemType;typedef struct LNode *PtrToNode; struct LNode {ElemType Data;PtrToNode Next; }; ...

  2. python通过什么对象连接数据库_「Python」连接数据库的三种方式

    连接SQLite 要操作关系数据库,首先需要连接到数据库,一个数据库连接称为Connection: 连接到数据库后,需要打开游标,称之为Cursor,通过Cursor执行SQL语句,然后,获得执行结果 ...

  3. 判断单链表中的元素是否递增_检测单链表中是否有环(C语言)

    检测单链表中是否有环(C语言) 方法:双指针法思路 使用两个指针,两个初始时都指向链表的头结点,然后one指针一次加一,另一个two指针一次加二. 在链表有环时,two指针与one指针相等就说明有环. ...

  4. 转载:看一遍就理解,图解单链表反转

    转载:看一遍就理解,图解单链表反转 看一遍就理解,图解单链表反转 前言 反转链表是程序员必备的基本素养,经常在面试.笔试的过程中出现.一直觉得反转链表实现代码不是很好理解,决定搬leetcode那道经 ...

  5. 链表节点合并排序:数组和单链表

    每日一贴,今天的内容关键字为链表节点 1 数组合并排序 1.1 合并两个已排序好的数组 需要额定的存储空间用来存储合并结果 //merge two array which are already so ...

  6. C语言面向对象编程(五):单链表实现

    前面我们介绍了如何在 C 语言中引入面向对象语言的一些特性来进行面向对象编程,从本篇开始,我们使用前面提到的技巧,陆续实现几个例子,最后呢,会提供一个基本的 http server 实现(使用 lib ...

  7. c语言将一个已知头结点的单链表逆序_C语言实现常用数据结构:静态链表数组实现(第5篇)...

    「今天是学习C语言第 148 天」 纸上学来终觉浅,绝知此事要躬行.-- 陆游「冬夜读书示子聿」 # 静态链表 使用数组实现,利用数组下标代替指针,从而实现数据结点之间的先后关系.实现要点: 1.数组 ...

  8. 【C语言】数据结构C语言版 实验3 带头结点的单链表

    slnklist.h #include <stdio.h> #include <stdlib.h> /************************************* ...

  9. 三种方式快速搭建vue环境项目全过程(图解)

    (一)环境搭建 1.下载源码 如果仅仅只是在项目或者某个文件中简单的使用vue,就可以直接在html中引入下列链接 <script src="https://unpkg.com/vue ...

最新文章

  1. 【CV】Python下载安装及环境变量配置教程
  2. js返回上一页实用的
  3. 安装与使用 Trac 来管理项目
  4. mysql 插入毫秒数据_【转载】怎样在mybatis里向mysql中插入毫秒数的时间?
  5. Spring Cloud Eureka(一)搭建一个注册中心
  6. ​“国产”AI框架争相开源,“领头羊”百度飞桨将扔重磅炸弹?
  7. 深圳车联网云服务商“麦谷科技”获5000万Pre A轮融资
  8. 性能进阶:使用JMeter进行websocket测试
  9. Expression Blend4 中文
  10. 细述 wxWindows
  11. 本科毕业论文查重标准是什么?
  12. 直播系统源码开发经验分享
  13. 银行票据+票据池相关的项目讲解
  14. Windows文件系统-NTFS文件系统
  15. Golang后端开发学习之路
  16. SpringCloud 基础架构搭建
  17. Linux常用命令速查手册——嘎嘎管用
  18. 华为云mysql qb文件恢复到本地-参考华为云官方文档
  19. Codeforces.838D.Airplane Arrangements(思路)
  20. 计算机专业感悟英语,学习计算机专业英语心得体会.docx

热门文章

  1. stm32f10x单片机进阶--spi使用
  2. css pointer-event
  3. 有用的Python模块 - pprint
  4. 数据库基础知识——初始MySQL
  5. 计算机组成原理——计算机系统的性能指标(机器字长、存储容量、运算速度)
  6. iar 连接linux开发板,LED裸机程序(IAR)
  7. oracle 表 上限,Oracle分区表(Partition Table)的数量限制
  8. linux源码下载阿帕奇,Ubuntu 12.04下源码安装Apache
  9. TensorFlow报错:'dict' object has no attribute 'SerializeToString'
  10. QT学习笔记(十四):QLayout的属性介绍