【面試官最愛考察的算法】單鏈表的反轉(java實現)

要求很簡單,輸入一個鏈表,反轉鏈表後,輸出新鏈表的表頭。反轉鏈表是有2種方法(遞歸法,遍歷法)實現的,面試官最愛考察的算法無非是斐波那契數列和單鏈表反轉,遞歸方法實現鏈表反轉比較優雅,可是對於不瞭解遞歸的同窗來講仍是有理解難度的。node

遞歸法

整體來講,遞歸法是從最後一個Node開始,在彈棧的過程當中將指針順序置換的。遞歸法實現圖面試

爲了方便理解,咱們以 1->2->3->4這個鏈表來作演示。輸出的效果是4->3->2->1算法

首先定義Node:bash

package cn.liuhaihua;public class Node<T> {    Node next;    T object;
    /**     * 構造函數     * @param next     * @param object     */    public Node(Node next,T object){        this.next=next;        this.object=object;    }}複製代碼

反轉方法以下:函數

/**     *  遞歸反轉     * @param node     * @return     */    public static Node reverse(Node node){        Node newnode =null;        if(null==node||null==node.next)        {            return node;        }else{            Node temp =  node.next;            newnode = reverse(node.next);            temp.next = node;            node.next=null;        }        print(newnode);        return newnode;    }複製代碼

遞歸實質上就是系統幫你壓棧的過程,系統在壓棧的時候會保留現場。ui

咱們來看是怎樣的一個遞歸過程:1->2->3->4this

程序到達Node newnode = reverse(node.next);時進入遞歸 咱們假設此時遞歸到了3結點,此時node=3結點,temp=3結點.next(其實是4結點) 執行Node newnode = reverse(node.next);傳入的node.next是4結點,返回的newnode是4結點。接下來就是彈棧過程了 程序繼續執行 temp.next = node就至關於4->3 node.next = null 即把3結點指向4結點的指針斷掉。返回新鏈表的頭結點newnodespa

注意:當return後,系統會恢復2結點壓棧時的現場,此時的node=2結點;temp=2結點.next(3結點),再進行上述的操做。最後完成整個鏈表的翻轉。3d

遍歷法

遍歷法就是在鏈表遍歷的過程當中將指針順序置換 指針

先上代碼:

public static Node reverseList(Node node) {  Node pre = null;  Node next = null;  while (node != null) {      next = node.next;      node.next = pre;      pre = node;      node = next;  }  return pre;}複製代碼

依舊是1->2->3->4 準備兩個空結點 pre用來保存先前結點、next用來作臨時變量 在頭結點node遍歷的時候此時爲1結點 next = 1結點.next(2結點) 1結點.next=pre(null) pre = 1結點 node = 2結點 進行下一次循環node=2結點 next = 2結點.next(3結點) 2結點.next=pre(1結點)=>即完成2->1 pre = 2結點 node = 3結點 進行循環...

最後附上完整的示例代碼

package cn.liuhaihua;
/** *單鏈表反序 */public class NodeReverse {    public static void main(String args[]){        Node<String> node_d = new Node<String>(null,"D");        Node<String> node_c = new Node<String>(node_d,"C");        Node<String> node_b = new Node<String>(node_c,"B");        Node<String> node_a = new Node<String>(node_b,"A");        System.out.println("反轉前:");        print(node_a);        System.out.println("反轉ing:");        //Node reversenode =reverse(node_a);        Node reversenode = reverseList(node_a);        System.out.println("反轉後:");        print(reversenode);


    }
    /**     *  遞歸反轉     * @param node     * @return     */    public static Node reverse(Node node){        Node newnode =null;        if(null==node||null==node.next)        {            return node;        }else{            Node temp =  node.next;            newnode = reverse(node.next);            temp.next = node;            node.next=null;        }        print(newnode);        return newnode;    }
    /**     * 遍歷反轉     * @param node     * @return     */    public static Node reverseList(Node node) {        Node pre = null;        Node next = null;        while (node != null) {            next = node.next;            node.next = pre;            pre = node;



複製代碼


相關文章
相關標籤/搜索