编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 01.单链表创建和使用
  • 02.双链表创建和使用
  • 03.循环链表创建和使用
  • 04.用单向链表实现栈
  • 05.合并两个排序的链表
  • 06.将单链表反转
  • 07.判断单链表是否有环
  • 08.取出有环链表中环的长度
  • 09.链表中环的入口结点
  • 10.两个链表第一个公共结点
  • 11.删除链表的倒数第N个节点
  • 12.获得单链表倒数第k个结点
  • 13.单链表中取出环的起始点
  • 14.两个单链表相交第一个交点
  • 15.复杂链表的复制
  • 16.求单链表中节点的个数
  • 17.从尾到头打印链表

06.将单链表反转

目录介绍

  • 01.题目要求
  • 02.问题分析
  • 03.实例代码

01.题目要求

  • 输入一个链表,反转链表后,输出链表的所有元素。
    例如链表:1->2->3->4
    反转之后:4->3->2->1

02.问题分析

2.1 一句话概括

  • 从头到尾遍历原链表,每遍历一个结点,将其摘下放在新链表的最前端。注意链表为空和只有一个结点的情况。时间复杂度为O(n)

2.2 解题思路

  • 链表的很常规的一道题,这一道题思路不算难,但自己实现起来真的可能会感觉无从下手,参考了别人的代码。
  • 思路就是我们根据链表的特点,前一个节点指向下一个节点的特点,把后面的节点移到前面来。
  • 就比如下图:我们把1节点和2节点互换位置,然后再将3节点指向2节点,4节点指向3节点,这样以来下面的链表就被反转了。
    • 链表
      链表

2.3 解题方法

  • ①遍历。将指向下一个节点的指针指向上一个节点。
  • ②递归。先让指向下一个节点的指针为空,然后递归调用,最后再将指向下一个节点的指针指向上一个节点。

03.实例代码

3.1 代码如下所示

  • 代码如下
    public class LinkList {
        public Node head;
        public Node current;
        
        class Node {
            //注:此处的两个成员变量权限不能为private,因为private的权限是仅对本类访问。
            int data; //数据域
            Node next;//指针域
            public Node(int data) {
                this.data = data;
            }
        }
        
        //方法:向链表中添加数据
        public void add(int data) {
            //判断链表为空的时候
            if (head == null) {//如果头结点为空,说明这个链表还没有创建,那就把新的结点赋给头结点
                head = new Node(data);
                current = head;
            } else {
                //创建新的结点,放在当前节点的后面(把新的结点合链表进行关联)
                current.next = new Node(data);
                //把链表的当前索引向后移动一位
                current = current.next;   //此步操作完成之后,current结点指向新添加的那个结点
            }
        }
    
        //方法:链表的反转
        public Node reverseList(Node head) {
    
            //如果链表为空或者只有一个节点,无需反转,直接返回原链表的头结点
            if (head == null || head.next == null) {
                return head;
            }
    
            Node current = head;
            Node next = null; //定义当前结点的下一个结点
            Node reverseHead = null;  //反转后新链表的表头
    
            while (current != null) {
                next = current.next;  //暂时保存住当前结点的下一个结点,因为下一次要用
    
                current.next = reverseHead; //将current的下一个结点指向新链表的头结点
                reverseHead = current;  
    
                current = next;   // 操作结束后,current节点后移
            }
    
            return reverseHead;
        }
    }
  • 测试方法
    public static void main(String[] args) {
        ListNode a = new ListNode(1);
        ListNode b = new ListNode(2);
        ListNode c = new ListNode(3);
        ListNode d = new ListNode(4);
        ListNode e = new ListNode(5);
        a.next = b;
        b.next = c;
        c.next = d;
        d.next = e;
        Node e = new LinkList().ReverseList(a);
        while (e != null) {
          System.out.println(e.val);
          e = e.next;
        }
    }
  • 结果如下所示
    5
    4
    3
    2
    1
  • 遍历
    /**
     * 反转单链表
     * @param head
     * @return
     */
    private static Node reverseHead(Node head) {
        if (head == null) {
            return head;
        }
        Node pre = head;
        Node cur = head.nextNode;
        Node next = null;
        while(cur != null){
            next = cur.nextNode;
            cur.nextNode = pre;
            pre = cur;
            cur = next;
        }
        head.nextNode = null;
        head = pre;
        return head;
    }
  • 递归
    /**
     * 递归反转
     * @param head
     * @return
     */
    private static Node reverseByRecur(Node current) {
        if (current == null || current.nextNode == null) return current;  
         Node nextNode = current.nextNode;  
         current.nextNode = null;  
         Node reverseRest = reverseByRecur(nextNode);  
         nextNode.nextNode = current;  
         return reverseRest;  
    }
贡献者: yangchong211
上一篇
05.合并两个排序的链表
下一篇
07.判断单链表是否有环