單向鏈表反轉(zhuǎn)(含圖解)

前言


上次講解了單向鏈表的原理《Java實(shí)現(xiàn)單向鏈表功能》,今天拓展一下實(shí)現(xiàn)鏈表的翻轉(zhuǎn)。
下面直接上代碼。

鏈表初始化


public class LinkedArray<T extends Number>{
    
    //鏈表的頭節(jié)點(diǎn)
    private Entry<T> head;
    
    //節(jié)點(diǎn)實(shí)體類
    static final class Entry<T>{
        //記錄當(dāng)前節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)
        Entry<T> next;
        T t;
        public Entry(T t) {
            // TODO Auto-generated constructor stub
            this.t = t;
        }
    }
}

添加節(jié)點(diǎn)


 public void add(T t) { 
    //根據(jù)參數(shù)創(chuàng)建一個(gè)節(jié)點(diǎn)
    Entry<T> entry = new Entry<T>(t);
    //當(dāng)鏈表為空時(shí),記錄head節(jié)點(diǎn)
    if(head == null) {
        head = entry;
    }else {
        //節(jié)點(diǎn)移動(dòng),并且賦值,保持head節(jié)點(diǎn)為新增加的entry
        entry.next = head;
        head = entry;
    }
}
添加的過程結(jié)合代碼注釋和下面圖片:
添加過程

鏈表反轉(zhuǎn)


public void reverse() {
    ///記錄current的節(jié)點(diǎn)是head大的下一個(gè)節(jié)點(diǎn)。
    Entry<T> current = head.next;

    //切斷head.next指向current,(當(dāng)前的head變?yōu)殒湵淼奈?,所以next為空)
    head.next = null;   
    while(current != null) {
        //記錄currentNext的節(jié)點(diǎn)是currentNext大的下一個(gè)節(jié)點(diǎn)。
        Entry<T> currentNext = current.next;
        //current.next反方向指向以前的節(jié)點(diǎn)
        current.next = head;
        //移動(dòng)head和current指針,到后面head重新成為頭節(jié)點(diǎn)
        head = current; 
        current = currentNext;
    }       
}
翻轉(zhuǎn)的過程結(jié)合代碼注釋和下面圖片:
翻轉(zhuǎn)過程.png

整個(gè)鏈表的插入以及翻轉(zhuǎn)就實(shí)現(xiàn)了,但是要注意的是鏈表中元素的順序是按照插入的順序,并不是按照元素實(shí)際數(shù)值的大小排序。下面拓展實(shí)現(xiàn)插入按照排序。

自然數(shù)序插入

本文只討論Number類型的順序排列


public void addByOrder(T t) {   
    //根據(jù)參數(shù)創(chuàng)建一個(gè)節(jié)點(diǎn)
    Entry<T> entry = new Entry<T>(t);
    //當(dāng)鏈表為空時(shí),記錄head節(jié)點(diǎn)
    if(head == null) {
        head = entry;
    }else {
        //從head開始,記錄上個(gè)節(jié)點(diǎn),
        //current是當(dāng)前節(jié)點(diǎn),previous為current的上一個(gè)節(jié)點(diǎn)
        Entry<T> current = head;
        Entry<T> previous = head;
            
        //遍歷整條鏈表,直到當(dāng)前current節(jié)點(diǎn)為空(鏈表已經(jīng)到尾部)
        //或者插入的樹數(shù)值比當(dāng)前current大
        while(current != null && t.doubleValue()>current.t.doubleValue()) {
            //節(jié)點(diǎn)移動(dòng)
            previous = current;
            current = current.next;
        }
            
        //當(dāng)前鏈表只有head一個(gè)節(jié)點(diǎn),
        //并且傳入大的數(shù)值比head小(因?yàn)閏urrent == previous,current節(jié)點(diǎn)并沒有移動(dòng))
        if(current == previous) {
            entry.next = head;
            head = entry;
        }else {
            //找到節(jié)點(diǎn)的位置,在previous和current的中間插入
            previous.next = entry;
            entry.next = current;
        }   
    }
}
添加的過程結(jié)合代碼注釋和下面圖片:
自然順序插入.png

運(yùn)行結(jié)果

主函數(shù)隨機(jī)輸入10個(gè)數(shù)字,測(cè)試排序與不排序的情況。

public static void main(String[] args) {
        // TODO Auto-generated method stub  
         add();
         System.out.println("-------------分割線-----------");
         addByOrder();
    }

    private static void add() {
        LinkedArray<Number> list = new LinkedArray<>();
        list.add(3);
        list.add(4);
        list.add(8);
        list.add(6);
        list.add(9);
        list.add(2);
        list.add(1);
        list.add(5);
        list.add(0);
        list.add(7);
        
        System.out.println(list.findAll());
        list.reverse();
        System.out.println(list.findAll());
    }
    
    private static void addByOrder() {
        LinkedArray<Number> list = new LinkedArray<>();
        list.addByOrder(3);
        list.addByOrder(4);
        list.addByOrder(8);
        list.addByOrder(6);
        list.addByOrder(9);
        list.addByOrder(2);
        list.addByOrder(1);
        list.addByOrder(5);
        list.addByOrder(0);
        list.addByOrder(7);
        
        System.out.println(list.findAll());
        list.reverse();
        System.out.println(list.findAll());
    }
運(yùn)行結(jié)果
結(jié)果.png

總計(jì)

上面討論了插入節(jié)點(diǎn),順序插入節(jié)點(diǎn)和翻轉(zhuǎn)的功能。鏈表需要重點(diǎn)理解清楚指針的移動(dòng)。更多的單向鏈表功能請(qǐng)參考《Java實(shí)現(xiàn)單向鏈表功能》

單向鏈表的功能實(shí)現(xiàn)到這里就結(jié)束了。
由于作者水平有限,如果錯(cuò)漏歡迎各位大神指出。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容