循环遍历法反转单向链表(附图)

最近有人聊到单向链表反转的相关问题,自己闲来无事研究一下。

先画图了解一下单向链表

在这里插入图片描述

看一下,一个链表有多个节点组成,每个节点指向下一个节点,最后一个的指向是null。

思路:从头节点开始设置头节的nextNode为null,当前节点的nextNode指向头节点,如此一来还需要定义一个nextNode来记录下一个节点,然后指针统一向右移动一位。三个重要角色:firstNode、currentNode、nextNode。

在这里插入图片描述

STEP 1

设置first节的nextNode为null

在这里插入图片描述

STEP 2

current节点的下一个节点指向first节点

在这里插入图片描述

STEP 3

让current节点的下一个节点指向first节点,并让“指针”右移一位。
  
current.setNextNode(firstNode);
first  = current;
current = next;
next = next.getNextNode();

在这里插入图片描述

STEP 4

以此类推,直到current的下一个节点为空(这里后面会看到)

在这里插入图片描述

如果while条件为 (current.getNextNode != null),此时会看到current和first是断开的,所以需要:

current.setNextNode(firstNode);

最后返回current。

有了思路上代码

准备一个链表节点

public class Node {
    private int date;

    private Node nextNode;

    public int getDate() {
        return date;
    }

    public void setDate(int date) {
        this.date = date;
    }

    public Node getNextNode() {
        return nextNode;
    }

    public void setNextNode(Node nextNode) {
        this.nextNode = nextNode;
    }
}

构造一个链表

Node head = new Node();
Node node1 = new Node();
Node node2 = new Node();
Node node3 = new Node();
Node node4 = new Node();
Node tail = new Node();

head.setDate(1);
head.setNextNode(node1);

node1.setDate(2);
node1.setNextNode(node2);

node2.setDate(3);
node2.setNextNode(node3);

node3.setDate(4);
node3.setNextNode(node4);

node4.setDate(5);
node4.setNextNode(tail);

tail.setDate(6);
tail.setNextNode(null);

遍历链表

Node temp = head;
while (temp != null){
    System.out.print(temp.getDate() + " -> ");
    temp = temp.getNextNode();
}

反转链表

public static Node revert(Node head){
  	// 惯性的校验参数
    if (head == null || head.getNextNode() == null) {
        return head;
    }
  	// 定义三个重要角色
    Node firstNode = head;			  // 记录头节点的位置
    Node current = head.getNextNode();// 记录当前节点的位置
    Node next = current.getNextNode();// 记录下一个节点的位置
		// 设置头节点指向null
    firstNode.setNextNode(null);
  	// 结束条件为当前节点的下一个节点不为null
    while (current.getNextNode() != null){
      	// 设置当前节点的下一个节点为firstNode
        current.setNextNode(firstNode);
      	// “指针”右移一位
        firstNode = current;
        current = next;
        next = next.getNextNode();
    }
  	// 现在当前节点的下一个节点还是指向null的,所以设置
    current.setNextNode(firstNode);
    return current;
}

完整代码

public class ConvertNodeTest {

    public static void main(String[] args) {
        
        Node head = new Node();
        Node node1 = new Node();
        Node node2 = new Node();
        Node node3 = new Node();
        Node node4 = new Node();
        Node tail = new Node();

        head.setDate(90);
        head.setNextNode(node1);
        node1.setDate(63);
        node1.setNextNode(node2);
        node2.setDate(984);
        node2.setNextNode(node3);
        node3.setDate(35);
        node3.setNextNode(node4);
        node4.setDate(76);
        node4.setNextNode(tail);
        tail.setDate(53);
        tail.setNextNode(null);
        // 反转前遍历
        Node temp = head;
        while (temp != null){
            System.out.print(temp.getDate() + " -> ");
            temp = temp.getNextNode();
        }
        System.out.println();
        // 反转后遍历
        Node revert = revert(head);
        Node temp2 = revert;
        while (temp2 != null){
            System.out.print(temp2.getDate() + " -> ");
            temp2 = temp2.getNextNode();
        }
    }

    public static Node revert(Node head){
        // 惯性的校验参数
        if (head == null || head.getNextNode() == null) {
            return head;
        }
        // 定义三个重要角色
        Node firstNode = head;         // 记录头节点的位置
        Node current = head.getNextNode();// 记录当前节点的位置
        Node next = current.getNextNode();// 记录下一个节点的位置
        // 设置头节点指向null
        firstNode.setNextNode(null);
        // 结束条件为当前节点的下一个节点不为null
        while (current.getNextNode() != null){
            // 设置当前节点的下一个节点为firstNode
            current.setNextNode(firstNode);
            // “指针”右移一位
            firstNode = current;
            current = next;
            next = next.getNextNode();
        }
        // 现在当前节点的下一个节点还是指向null的,所以设置
        current.setNextNode(firstNode);
        return current;
    }
}

输出结果

90 -> 63 -> 984 -> 35 -> 76 -> 53 -> 
53 -> 76 -> 35 -> 984 -> 63 -> 90 -> 

时间复杂度

O(n)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值