链表反转?面试官你确定要让手写这个吗?

前言:

使用递归、遍历、双指针法 三种方式来实现单链表的反转;

 代码展示:

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class Node<T> {
    // 节点的数据域
    public T value;
    // 节点的指针域
    public Node next;

    // 构造方法
    public Node(T value) {
        this.value = value;
    }

    // 遍历链表
    public static void iter(Node n) {
        while (n != null) {
            System.out.print(n.value + " --> ");
            n = n.next;
        }
        System.out.print("null");
        System.out.println();
    }

    // 使用 递归 实现单链表反转
    public static Node reverse(Node head) {
        if (head == null || head.next == null) {
            return head;
        }
        // 获取头结点的下个节点,使用temp临时节点存储
        Node temp = head.next;
        // 递归调用
        Node node = reverse(head.next);
        // 将头节点下一个节点的指针域指向头节点
        temp.next = head;
        // 将头节点的指针域置为null
        head.next = null;
        return node;
    }

    // 使用 遍历+辅助空间 进行链表反转
    public static Node reverseOther(Node head) {
        List<Node> list = new ArrayList<Node>();

        while (head != null) {
            list.add(head);
            head = head.next;
        }

        for (int i = list.size() - 1; i > 0; i--) {
            Node n = list.get(i);
            Node n1 = list.get(i-1);
            n.next = n1;
            n1.next = null;
        }
        // 返回头结点
        return list.get(list.size() - 1);
    }


    // 使用 双指针+辅助临时节点 进行链表反转
    public static Node reverseTwo(Node head) {
        // 当前节点指针
        Node current ;
        // 前一节点指针
        Node previous;
        // 当前节点指针初始化指向头结点
        current = head;
        // 前一节点指针初始化为 null
        previous = null;

        while(current != null){
            // 辅助的临时节点, 存储当前节点的下一个节点
            Node temp = current.next;
            // 当前节点的下一个节点指向了前一个节点指针指向的节点
            current.next = previous;
            // 然后 前一节点指针向前移动一个节点,此时和当前节点指针都指向了当前节点
            previous = current;
            // 当前节点指针也向前移动一个节点,也就是移动到了当前节点的下一个节点,就是临时节点指向的节点
            current = temp;
        }
        // 返回头结点
        return previous;
    }


    // 创建链表,返回头结点
    public static Node createList(){
        // 头节点
        Node<String> head;

        Node<String> n = new Node<String>("666");
        Node<String> n1 = new Node<String>("555");
        Node<String> n2 = new Node<String>("444");
        Node<String> n3 = new Node<String>("333");
        Node<String> n4 = new Node<String>("222");
        // 指定头节点
        head = n;
        n.next = n1;
        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        // 返回头结点
        return head;
    }


    // test
    public static void main(String[] args) {
        Node head ;

        // 创建链表
        head = createList();
        // 遍历创建的链表
        iter(head);

        // 递归反转反转
        head = reverse(head);
        // 遍历递归反转后的单链表
        iter(head);

        // 使用 便利+辅助空间 将反转后的单链表反转回来
        head = reverseOther(head);
        // 遍历反转回来的单链表
        iter(head);

        // 使用 双指针+辅助临时节点 将反转回来的单链表再次反转,并遍历
        iter(reverseTwo(head));
    }
}

 

不要忘记留下你学习的足迹 [点赞 + 收藏 + 评论]嘿嘿ヾ

一切看文章不点赞都是“耍流氓”,嘿嘿ヾ(◍°∇°◍)ノ゙!开个玩笑,动一动你的小手,点赞就完事了,你每个人出一份力量(点赞 + 评论)就会让更多的学习者加入进来!非常感谢! ̄ω ̄=

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章