鏈表反轉?面試官你確定要讓手寫這個嗎?

前言:

使用遞歸、遍歷、雙指針法 三種方式來實現單鏈表的反轉;

 代碼展示:

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));
    }
}

 

不要忘記留下你學習的足跡 [點贊 + 收藏 + 評論]嘿嘿ヾ

一切看文章不點贊都是“耍流氓”,嘿嘿ヾ(◍°∇°◍)ノ゙!開個玩笑,動一動你的小手,點贊就完事了,你每個人出一份力量(點贊 + 評論)就會讓更多的學習者加入進來!非常感謝! ̄ω ̄=

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