链表反转的四种方法分析

本文详细介绍了链表反转的四种方法,包括非递归的增加节点法、反转两个节点次序法、单次指针移动法以及递归解法。通过分析,指出第三种方法在不增加额外节点的情况下,指针移动次数最少,效率最高。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于反转链表的总结:
反转链表的方式有很多,现在介绍四种:
非递归的:






从图中可以看到,对n个节点的反转,方法一指针指向改变了2^(n-1)次,还有一个额外的节点,而方法二用了2^(n-1)次,却没有增加额外节点。方法三既没有增加新节点,指针指向改变了n次,显然方法三好。
递归方法很赞,图就不好画了,大家直接看代码。

代码:
package OfferTest;
 
import java.util.HashMap;
 
/**
 * class ListNode
 * @author cyc
 *
 */
public class ListNode {
    int val;
    ListNode next;
    ListNode(int x){
        val = x;
    }
    /**
     * print List from its head node
     * @param head
     */
    public static void printList(ListNode head){
        HashMap<ListNode, Boolean> hm = new HashMap<ListNode, Boolean>(); 
        ListNode mv = head; 
        while(mv!=null){
            if(!hm.containsKey(mv)){
                System.out.print(mv.val+"——>");
                hm.put(mv, true);
                mv = mv.next;
            }
            else{
                System.out.print(mv.val+" is the circle List\n");
                return;
            }
        }
        System.out.print("null\n");
    }
    /**
     * Transfer int[] array to List
     * @param array
     * @return ListNode
     */
    public static ListNode arrayToList(int[] array){
        if(array.length==0){
            return null;
        }
        else{
            ListNode head = new ListNode(array[0]);
            ListNode end = head;
            for(int i=1; i<array.length; i++){
                ListNode tmpNode = new ListNode(array[i]);
                end.next = tmpNode;
                end = end.next;
            }
            end.next = null;
            return head;
        }
    }
}

package OfferTest;
 
public class ReverseList {
    public static void main(String[] args) {
        int[] array = {1,2,3};
        ListNode head = ListNode.arrayToList(array);
        ReverseList rl = new ReverseList();
        head = rl.reverseList1(head);
        ListNode.printList(head);
        head = rl.reverseList2(head);
        ListNode.printList(head);
        head = rl.reverseList3(head);
        ListNode.printList(head);
        head = rl.recusionList(head);
        ListNode.printList(head);
    }
    /**
     * 增加节点法
     * @param head
     * @return
     */
    public ListNode reverseList1(ListNode head){
        //增加一个新的节点newHead
        ListNode newHead = new ListNode(0);
        newHead.next = null;
        ListNode cur;
        while(head!=null){
            cur = head;
            head = head.next;
            cur.next = newHead.next;
            newHead.next = cur;
        }
        return newHead.next;
    }
    /**
     * 反转两个节点的次序,需要指针移动两次
     * @param head
     * @return
     */
    public ListNode reverseList2(ListNode head){
        if(head==null||head.next==null){
            return head;
        }
        ListNode cur = head.next;
        ListNode end = head;
        while(cur!=null){
            end.next = cur.next;
            cur.next = head;
            head = cur;
            cur = end.next;
        }
        return head;
    }
    /**
     * 反转两个节点时,移动一次指针
     * @param head
     * @return
     */
    public ListNode reverseList3(ListNode head){
        if(head==null||head.next==null){
            return head;
        }
        ListNode cur = head.next;
        ListNode tmp;
        head.next = null;
        while(cur!=null){
            tmp = cur.next;
            cur.next = head;
            head = cur;
            cur = tmp;
        }
        return head;
    }
    /**
     * 递归解法
     * @param head
     * @return
     */
    public ListNode recusionList(ListNode head){
        if(head==null||head.next==null){
            return head;
        }
        ListNode nextHead = recusionList(head.next);
        head.next.next = head;
        head.next = null;
        return nextHead;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值