单向链表的翻转

一、题目

将一个单向链表翻转,使其空间复杂度是O(1),时间复杂度是O(n)

二、解题思路

1、有如下链表
这里写图片描述

2、设置三个变量pre,pointer和next,分别指向链表中的前节点、要翻转的节点和后节点,如下图
这里写图片描述
(1)令pointer节点指向pre
(2)pre指向pointer指向的节点即节点1,pointer指向next指向的节点即节点2,
next指向next的下一节点即节点3,循环执行n次即可将链表翻转

这里写图片描述

当时对空间复杂度并不了解,以为只能设一个变量进行翻转,导致这题写不出来

三、核心代码

/**
    * @Title: reverseLinkedList
    * @Description: 将链表翻转
    * @param head 链表头
    * @return   
    * @return MyLinkedList    返回类型
    * @throws
    */ 
    public static MyLinkedList reverseLinkedList(Node head){

        //若链表为空或者链表只有一个节点,则直接返回,不需要翻转
        if (head != null && head.next != null) {
            Node preNode=null;
            Node pointer=head;
            Node nextNode=pointer.next;
            while (nextNode!=null) {
                pointer.next=preNode;
                preNode=pointer;
                pointer=nextNode;
                nextNode=nextNode.next;
            }
            pointer.next=preNode;
            return new MyLinkedList(pointer, head);
        }

        return new MyLinkedList(head, null);

    }

四、完整代码

package LinkedList;

public class MyLinkedList {

    private Node head;
    private Node last;


    public MyLinkedList(){
        head=null;
        last=null;
    }



    public MyLinkedList(Node head, Node last) {
        this.head = head;
        this.last = last;
    }



    /**
    * @Title: add
    * @Description: 将元素加进链表
    * @param elem   元素
    * @return void    返回类型
    * @throws
    */ 
    public int add(int elem){
        Node node = new Node(elem);

        if (head==null) {
            head=node;

        }else {
            last.next=node;
        }
        last=node;
        return elem;
    }


    /**
    * @Title: add
    * @Description: 将节点加进链表
    * @param node   节点
    * @return void    返回类型
    * @throws
    */ 
    public Node add(Node node) {
        if (head==null) {
            head=node;
        }else {
            last.next=node;
        }
        last=node;
        return node;
    }


    /**
    * @Title: reverseLinkedList
    * @Description: 将链表翻转
    * @param head 链表头
    * @return   
    * @return MyLinkedList    返回类型
    * @throws
    */ 
    public static MyLinkedList reverseLinkedList(Node head){

        //若链表为空或者链表只有一个节点,则直接返回,不需要翻转
        if (head != null && head.next != null) {
            Node preNode=null;
            Node pointer=head;
            Node nextNode=pointer.next;
            while (nextNode!=null) {
                pointer.next=preNode;
                preNode=pointer;
                pointer=nextNode;
                nextNode=nextNode.next;
            }
            pointer.next=preNode;
            return new MyLinkedList(pointer, head);
        }

        return new MyLinkedList(head, null);

    }


    /**
    * @Title: printLinkedList
    * @Description: 输出链表的各节点元素
    * @param head   
    * @return void    返回类型
    * @throws
    */ 
    public static void printLinkedList(Node head){
        Node pointer=head;
        while (pointer!=null) {
            System.out.println(pointer.data);
            pointer=pointer.next;
        }
    }





    public Node getHead() {
        return head;
    }



    public void setHead(Node head) {
        this.head = head;
    }



    public Node getLast() {
        return last;
    }



    public void setLast(Node last) {
        this.last = last;
    }





    /**
    * @ClassName: Node
    * @Description: 节点
    * @author kooking
    * @date 2018-6-29 下午4:20:18
    */ 
    class Node{
        private  int data;
        private Node next;
        public int getData() {
            return data;
        }
        public void setData(int data) {
            this.data = data;
        }
        public Node getNext() {
            return next;
        }
        public void setNext(Node next) {
            this.next = next;
        }
        public Node() {
            this.data=0;
            this.next=null;
        }

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

    }



}




五、测试代码

public class MyLinkedListTest {

    @Test
    public void test(){
        MyLinkedList list=new MyLinkedList();
        //创建链表
        for (int i = 0; i < 10; i++) {
            list.add(i);
        }
        //打印链表
        MyLinkedList.printLinkedList(list.getHead());

        //翻转链表
        MyLinkedList reverseLinkedList = MyLinkedList.reverseLinkedList(list.getHead());
        //打印翻转后的链表
        System.out.println("翻转后的链表=================================");
        MyLinkedList.printLinkedList(reverseLinkedList.getHead());

    }
}

六、测试结果

0
1
2
3
4
5
6
7
8
9
翻转后的链表=================================
9
8
7
6
5
4
3
2
1
0

有关链表的其他问题请看我另一篇博客关于链表的一些操作——判断是否有环、寻找入口点等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值