使用递归实现链表反转
链表反转(图解)
文章目录
- 链表反转(图解)
- 前言
- 一、链表反转
- 二、递归思想
- 三、具体实现
- 1.反转方法API
- 2.具体实现代码
- 3.方法测试
- 四、方法调用过程
- 总结
前言
链表反转是面试中的一个高频题目,可以通过多种方法实现,例如循环,递归;本篇文章将使用递归对链表实现反转。
一、链表反转
例如,给定一个单链表,原链表中的数据为: 1–>2–>3–>,反转后的链表为:4–>3–>2–>1。
二、递归思想
递归,有”递“还要有”归“,所谓递归,就是会在函数内部代码中,调用这个函数本身,所以,我们必须要找出递归的结束条件,否则会一直调用自己,造成死循环,从而栈内存溢出。也就是说,我们需要找出当方法的参数符合某一条件时,递归结束,之后把结果返回。使用递归反转其实就是从链表第一个存数据的节点开始,一次递归调用反转每一个节点,直到把最后一个节点反转完毕,整个链表就反转完毕。
三、具体实现
1.反转方法API
public void reverse():对整个链表反转
public void reverse(Node curr):反转链表中的某个节点,并把反转后的节点返回
2.具体实现代码
(链表的实现代码见另一篇文章:链式存储结构–单向链表的实现戳这儿
public void reverse(){if (isEmpty()){return;}reverse(head.next);}public Node reverse(Node curr){if (curr.next == null){//如果curr是最后一个节点,让头节点指向它head.next = curr;return curr;}//递归反转当前节点curr的下一个节点,返回值是链表反转后当前节点的上一个节点Node pre = reverse(curr.next);//让返回的下一个节点成为当前节点currpre.next = curr;//使节点原来的指向为空curr.next = null;return curr;}
3.方法测试
测试结果:
四、方法调用过程
main方法进栈:
在main方法中调用reverse()方法,reverse()方法进栈。
reverse() 方法调用带重载的reverse(1) 方法。(此时reverse的参数curr=1,此处简写为reverse(1))reverse(1) 方法进栈,当方法执行到Node pre = reverse(2)时,调用带重载的reverse(2) 方法。
reverse(2) 方法进栈,当方法执行到Node pre = reverse(3)时,调用带重载的reverse(3) 方法。
reverse(3) 方法进栈,当方法执行到Node pre = reverse(4)时,调用带重载的reverse(4) 方法。
reverse(4) 方法进栈, 当执行reverse(4) 方法时, 进行判断curr.next == null ,此时满足条件,使头结点指向 4 这个结点 ,然后,该方法将该节点返回给reverse(3).(reverse(4) 执行完毕出栈)
此时使head节点指向该curr节点,curr = 4;
接下来reverse(3) 接收 reverse(4) 的返回值,此时 当前pre 是4结点 ,执行剩余的代码;
pre.next = curr; 将 4 结点 的下一个结点指向 3 结点;
curr.next = null; 将 3 结点 的下一个结点指向 null (使3 结点原本指向指向4结点的指针断开)
reverse(3) 执行完毕后,将返回值(返回的是3结点)给 reverse(2) , 然后出栈。
紧接着 reverse(2) 接收 reverse(3) 的返回值 此时 当前pre 是3结点 ,执行剩余代码;
pre.next = curr; 将 3 结点 的下一个结点指向 2 结点;
curr.next = null; 将 2 结点 的下一个结点指向 null; (使2结点原本指向指向3结点的指针断开)
reverse(2) 执行完毕后,将返回值(返回的是2结点)给 reverse(1) , 然后出栈。
最后reverse(1) 接收 reverse(2) 的返回值 此时pre 是2结点 ,执行剩余的代码;
pre.next = curr; 将 2 结点 的下一个结点指向 1 结点;
curr.next = null; 将 1 结点 的下一个结点指向 null ;(使1结点原本指向指向2结点的指针断开)
reverse(1) 执行完毕后,将返回值(返回的是1结点)给 reverse() 方法(该方法没有使用变量接收返回值 ), 然后出栈。
至此,程序执行完毕,使用递归反转单链表的功能已经实现。
方法调用内存图如下:
总结
综上,递归实现链表反转代码并不复杂,难度在于去理解这个递归调用的整个逻辑。
使用递归实现链表反转相关推荐
- 循环控制-链表反转(与创建链表)
0.目录 1.循环控制 2.Java代码实现 2.1 创建链表和递归反转实现 2.2 循环反转思路 2.3 链表反转的实现 2.4 测试用例 2.5 循环控制-创建链表 1.循环控制 循环书写方法: ...
- Swift 链表反转
反转链表主要目的是节省内存空间,不用开辟新的内存空间,在原来的空间进行操作. 若要进行增删操作就可以在具体某个节点进行增删,然后把前后节点拼接在一起,从而组成新的链表. class LinkNode& ...
- C++递归与非递归实现链表的反转
思想参考:http://ceeji.net/blog/reserve-linked-list-cpp/ #include"list.h" using namespace std; ...
- 翻转链表python递归_Python实现链表反转的方法【迭代法与递归法】
导读 这篇文章主要介绍了Python实现链表反转的方法,结合实例形式分析了Python迭代法与递归法实现链表反转的相关操作技巧与注意事项,需要的朋友可以参考下 本文实例讲述了Python实现链表反转的 ...
- 单链表反转(递归和非递归)
单链表反转有递归和非递归两种算法. 下面定义节点 [cpp] view plaincopy typedef struct ListNode{ int value; ListNode* next; }L ...
- 数据结构基础篇-链表反转(非递归与递归)C++实现
链表反转C++代码,附加打印逆序链表(不进行反转)代码. 测试用例: 5 2 3 4 10 5 1 4 1.非递归实现 思路:需要三个指针p1.p2.p3,分别指向上一个节点.当前节点与缓存的下一个节 ...
- java 链表反转 递归_递归法的理解——以反转链表为例
2020-01-07 递归是什么: 递归,从定义上说,指的是某个函数直接或者间接调用自己时,则发生了递归. 比如说著名的斐波拉契数列的实现方法之一: 1 public static int f(int ...
- 链表反转 递归实现Java
啊 就因为我实现单链表时多一个头结点 差点-平安夜快乐 虽然是明天晚上 不过是我梦开始的时间. package com.zhang;public class Solution {//先构造一个简单的单 ...
- 实现链表反转(迭代法,递归法)
反转前: 反转后: 迭代法 实现思路: 迭代法实现链表反转的思路其实很简单,反转之前链表的节点的指针域指向的是下一个节点,反转之后我们只需要将当前节点的指针域指向前一个节点,由于是单链表,只能通过节点 ...
最新文章
- 苏宁零售云 App 稳定保障实践
- Docker折腾手记-linux下安装
- 10、 HAVING:过滤分组
- 我的世界梦之边缘5服务器在维护吗,8月5日服务器例行维护公告(已完成)
- 《移动项目实践》实验报告——Android自定义控件
- 你可以通过这13种方法帮助Linux发展
- linux下开发问题汇总
- Java中的基本数据类型转换(自动、强制、提升)
- Federated learning论文修改2021-11-14(X-Y Liang)
- 逆序创建链表及链表反转和中间位置反转
- 离上市又近一步!华为P40系列在工信部入网......
- 中通科技移动自动化测试的革新与探索
- 随想录(学习《许式伟的架构课》)
- SSH连接原理及ssh-key
- 利用nexus搭建maven库并利用AS上传aar
- maven 手动安装ojdbc7
- esxi能直通的显卡型号_显卡刷bios教程
- 菜鸟也疯狂,易语言自绘控件__进度条、滑块条
- 计算机msvcp100.dll,msvcp100.dll丢失的解决方法
- 自动驾驶汽车硬件与软件技术介绍
热门文章
- 大数据学习笔记-hadoop(1)
- C++数据结构——中序遍历二叉树
- android取QQ昵称,Android仿QQ复制昵称效果
- 2022年全球市场厨房油烟机灭火系统总体规模、主要生产商、主要地区、产品和应用细分研究报告
- 数据库数据类型 - char() 填坑
- 57岁大妈别样的套路,开超市竟然去卖袋子?这点子让人佩服!
- 设计模式之美总结(行为型篇)
- 最新ChatGPT GPT-4 相似匹配Embedding技术详解(附ipynb与python源码及视频讲解)——开源DataWhale发布入门ChatGPT技术新手从0到1必备使用指南手册(一)
- ROS 摄像头参数标定
- kettle 作业调度