前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >单链表反转Java版

单链表反转Java版

作者头像
WindCoder
发布2020-01-21 15:32:47
8930
发布2020-01-21 15:32:47
举报
文章被收录于专栏:WindCoderWindCoder

头插法与尾插法

本文主要用头插法实现单链表的反转,开始前先简单了解一下头插法与尾插法。

头插法:

在头节点的后面进行插入操作,后一个插入进来的值,在前一个插入进来的值与头节点之间。

尾插法:

设法找到插入结点的上一个结点,总而言之,尾插法就是要使后面插入的结点在前一个插入结点和NULL值之间。

链表反转

链表反转又可分为带逻辑头结点反转和不带逻辑头节点的反转,区别就是反转过程中是否单独设置一个逻辑头结点,具体可见代码。

设节点类为Node:

代码语言:javascript
复制
public static class Node{
    private int data;
    private Node next;

    public Node(int data, Node next) {
        this.data = data;
        this.next = next;
    }

    public int getData() {
        return data;
    }

    public void setNext(Node next) {
         this.next = next;
    }

    public Node getNext() {
        return next;
    }
}

为方便阅读,之后不再调用Node的Setters/Getters函数,直接用其属性。

带逻辑头节点的反转

代码语言:javascript
复制
/**
* 输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
* @param head
* @return
*/
public static Node reverseList_head(Node head) {
    // 创建一个临时结点,当作头插法的逻辑头结点
    Node root = new Node(0, null);
    // 逻辑头结点点的下一个结点为空
    root.next = null;
    // 用于记录要处理的下一个结点
    Node next;
    // 当前处理的结点不为空
    while (head != null) {
        // 记录要处理的下一个结点
        next = head.next;
        // 当前结点的下一个结点指向逻辑头结点的下一个结点
        head.next = root.next;
        // 逻辑头结点的下一个结点指向当前处理的结点
        root.next = head;
        // 上面操作完成了一个结点的头插
        // 当前结点指向下一个要处理的结点
        head = next;
    }
    // 逻辑头结点的下一个结点就是返回后的头结点
    return root.next;
}

不带逻辑头节点的反转

该函数中不再有上面代码中开头创建的临时节点root。

代码语言:javascript
复制
/**
* 定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
* @param list
* @return
*/
public Node reverseList(Node list){
    if (list == null || list.getNext() == null) return list;
    // 用于记录当前处理的结点的
    Node curre = list;
    // 用于记录当前结点的前驱结点
    // 前驱结点开始为null,因为反转后的最后一个结点的下一个结点,即null
    // 也是反转链表的头结点
    Node pre = null;
    // 当前结点的下一个结点
    Node next = null;
    // 对链表进行头插法操作
    while (curre!=null){
        // 记录要处理的下一个结点
        next = curre.next;
        // 当前结点的下一个结点指向前驱结点,这样当前结点就插入到了反转链表的头部
        curre.next = pre;
        // 记录当前结点为前驱结点,完成一次头插
        pre = curre;
        // 当前结点指向下一个要处理的结点
        curre = next;
    }
    return pre;
}

再略微修改一下,可减少一次循环,本质上没区别,仅是因为最后一个结点肯定是反转后的头结点,所以省掉了最后一次循环:

代码语言:javascript
复制
public Node inverseLinkList(Node list){
    if (list == null || list.next == null) return list;

    Node pre = null;
    Node curre = list;
    Node next = null;

    while (curre.next!=null){
        next = curre.next;
        curre.next = pre;
        pre = curre;
        curre = next;
    }
    curre.next = pre;
    return curre;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 头插法与尾插法
    • 头插法:
      • 尾插法:
      • 单链表反转
        • 带逻辑头节点的反转
          • 不带逻辑头节点的反转
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档