算法通关村第二关 | 终于学会链表反转了 | java

84 阅读1分钟

图片.png

1.直接操作

链表反转后的效果如图:

c366719bbec5c1867e46477a26d16eb.jpg 我们将使用三个指针来进行操作,pre是指向新链表的头节点(<1>状态尚未进行操作,旧链表为空),cur是指向待反转链表的头节点,也是当前要反转的节点,next是下一个反转的节点。

a3f0a916fd4e8ee943542f9a0fd2ca1.jpg

public ListNode reverseList(ListNode head) {
        ListNode cur = head;
        ListNode next = null;
        ListNode pre = null;
        while(cur!=null){
            next = cur.next;//保存下一个待反转节点
            cur.next = pre;//为新链表插入节点
            pre = cur;//指定为新链表的头节点
            cur = next;
        }
        return pre;
    }

2.使用虚拟节点

头插法引用了一个虚拟节点(dummyNode)来进行操作,使得反转过程更好理解。

d1eedc16e95ad93df2363f367b8d851.jpg

public ListNode reverseList(ListNode head) {
        ListNode dummy = new ListNode(-1,null);
        ListNode cur = head;
        ListNode next = null;
        while(cur!=null){
           next = cur.next;//保存下一个待反转节点
           cur.next = dummy.next;//反转当前节点
           dummy.next = cur;
           cur = next;
        }
        return dummy.next;
    }

3.递归法

public ListNode reverseList(ListNode head) { 
    if (head == null || head.next == null) return head; //出口
    ListNode newHead = reverseList(head.next);
    head.next.next = head;
    head.next = null; 
    return newHead;
} 

4.使用栈

把全部元素压栈,每次出栈都指向下一个出栈元素。

  public ListNode reverseList(ListNode head) {
        Stack<ListNode> s = new Stack();
        ListNode temp = new ListNode(-1,null);
        ListNode dummy = temp;
        while(head!=null){//全部压栈
            s.push(head);
            head = head.next;
        }
        while(s.size()>0){
            temp.next = s.pop();
            temp = temp.next;
        }
        temp.next = null;//防止成环
        return dummy.next;