Java實(shí)現(xiàn)簡(jiǎn)單的鏈表-面向初學(xué)者

很久之前用C語(yǔ)言實(shí)現(xiàn)過(guò)鏈表佃牛,現(xiàn)在已經(jīng)太久沒(méi)用C語(yǔ)言。就先用JAVA實(shí)現(xiàn)一個(gè)簡(jiǎn)單鏈表好了医舆,還是使用最原始的C語(yǔ)言實(shí)現(xiàn)的思路俘侠,想來(lái)語(yǔ)言變了實(shí)現(xiàn)方式大同小異吧。后續(xù)可能會(huì)不斷實(shí)現(xiàn)不一樣的數(shù)據(jù)結(jié)構(gòu)蔬将。

  • 節(jié)點(diǎn)
    先確定節(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu)(一個(gè)節(jié)點(diǎn)一個(gè)數(shù)字好了)爷速,后續(xù)慢慢一點(diǎn)點(diǎn)擴(kuò)展:
/**
 * @author hsf
 * @description
 * @create 2018-07-14 下午3:47
 **/

public class Node {
    //數(shù)據(jù)
    public int value;
    //下一節(jié)點(diǎn)
    public Node next;

}

或許我需要換一個(gè)習(xí)慣的寫(xiě)法;

/**
 * @author hsf
 * @description
 * @create 2018-07-14 下午3:47
 **/

public class Node {
    //數(shù)據(jù)
    private int value;
    //下一節(jié)點(diǎn)
    private Node next;

    public int getValue() {
        return value;
    }

    public Node setValue(int value) {
        this.value = value;
        return this;
    }

    public Node getNext() {
        return next;
    }

    public Node setNext(Node next) {
        this.next = next;
        return this;
    }
}

這個(gè)時(shí)候其實(shí)就可以創(chuàng)建一個(gè)鏈表了,直接創(chuàng)建main方法吧霞怀;

public static void main(String [] args){
    //頭節(jié)點(diǎn)
    Node head = new Node();
    head.setValue(-1);
    head.setNext(null);
    //第一個(gè)節(jié)點(diǎn)
    Node firstNode = new Node();
    firstNode.setValue(0);
    firstNode.setNext(null);
    //鏈接
    head.setNext(firstNode);
    System.out.println(head.getValue() + 
    " " +head.getNext().getValue());
}

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


WX20180714-164038@2x.png

這可能是最簡(jiǎn)陋的鏈表了惫东。
繼續(xù)加工,把可以封裝的封裝起來(lái)毙石,能增加的增加廉沮。
給節(jié)添加構(gòu)造函數(shù):

public Node(int value,Node next){
    this.value =value;
    this.next = next;
}

public Node(int value){
    this.value = value;
}

public Node(){}

封裝幾個(gè)方法

public boolean hasNext(){
    return this.next == null ? false : true;
}

public Node addToNext(Node node){
    this.next = node;
    return node;
}

改造main方法:

ublic static void main(String [] args){
    //頭節(jié)點(diǎn)
    Node head = new Node(-1);
    //第一個(gè)節(jié)點(diǎn)
    Node firstNode = new Node(0);
    //第二個(gè)節(jié)點(diǎn)
    Node secondNode = new Node(1);
    //鏈接
    head.addToNext(firstNode);
    firstNode.addToNext(secondNode);
    System.out.println(head.getValue() + 
            " " +head.getNext().getValue() + 
            " " +head.getNext().getNext().getValue());
}

說(shuō)實(shí)話這個(gè)輸出方式有些蠢,需要一個(gè)新的方式輸出徐矩,這里就寫(xiě)一個(gè)輸出方法滞时,效果就是以當(dāng)前節(jié)點(diǎn)為頭,輸出以后的所有節(jié)點(diǎn)滤灯。
繼續(xù)改造Node類

//直接重寫(xiě)toString好了
@Override
public String toString() {
    String val = Integer.toString(value);
    if(next != null){
        val = val.concat(" hasNext ");
        val = val.concat(next.toString());
    }
    return val;
}

這樣就直接可以輸出了坪稽,當(dāng)然也可以使用循環(huán)方法實(shí)現(xiàn)。原來(lái)的輸出直接換成

System.out.println(head);

輸出


WX20180714-170151@2x.png

這是有個(gè)問(wèn)題我假如需要加入一個(gè)節(jié)點(diǎn)到尾部怎么辦呢鳞骤,也就是也就是尾插法,新增一個(gè)方法:

//先找到尾巴窒百,在插入就好了  需要的話可以返回尾節(jié)點(diǎn)。
public void addToTail(Node node){
    Node temp = this;
    while(temp.hasNext()){
        temp = temp.next;
    }
    temp.next = node;
}

既然有尾插法豫尽,那么就應(yīng)該來(lái)一個(gè)頭插法贝咙,頭插法一般需要一個(gè)頭節(jié)點(diǎn),方法可以這么實(shí)現(xiàn)拂募。

//現(xiàn)將新節(jié)點(diǎn)的值指向原有頭節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)庭猩,再將頭節(jié)點(diǎn)指向新節(jié)點(diǎn)
public void addToHead(Node head,Node node){
    node.next = head.next;
    head.next = node;
}

當(dāng)我需要往指定的位置插入一個(gè)節(jié)點(diǎn)的時(shí)候就想到了之前寫(xiě)的一個(gè)方法addToNext,此時(shí)再詳細(xì)看這個(gè)方法會(huì)發(fā)現(xiàn)陈症,這里的這個(gè)方法有問(wèn)題蔼水,這里只是純粹的再在當(dāng)前節(jié)點(diǎn)后面添加,而不管這個(gè)節(jié)點(diǎn)之后是不是已經(jīng)有節(jié)點(diǎn)录肯。這樣的會(huì)造成鏈表被截?cái)嗯恳浮P薷脑蟹椒ǎ黾渔溄釉泄?jié)點(diǎn)到新節(jié)點(diǎn)论咏。

public Node addToNext(Node node){
    node.next = this.next;
    this.next = node;
    return node;
}

最終main函數(shù)測(cè)試:

public static void main(String [] args){
    //頭節(jié)點(diǎn)
    Node head = new Node(-1);
    //第一個(gè)節(jié)點(diǎn)
    Node firstNode = new Node(0);
    //第二個(gè)節(jié)點(diǎn)
    Node secondNode = new Node(1);
    //鏈接
    head.addToNext(firstNode);
    //加入第二個(gè)節(jié)點(diǎn)
    firstNode.addToNext(secondNode);
    //向尾部添加節(jié)點(diǎn)
    head.addToTail(new Node(2));
    //向頭部添加節(jié)點(diǎn)
    head.addToHead(head,new Node(3));
    //向中間添加節(jié)點(diǎn)
    secondNode.addToNext(new Node(4));
    //輸出
    System.out.println(head);
}

最終輸出:


WX20180714-233034@2x.png

以上是一個(gè)單項(xiàng)鏈表簡(jiǎn)單實(shí)現(xiàn)优炬;

  • 單向鏈表逆轉(zhuǎn)
    假設(shè)只知道一個(gè)頭節(jié)點(diǎn)。難度其實(shí)在于單向鏈表在沒(méi)有指向前趨節(jié)點(diǎn)的情況下怎么獲取到前驅(qū)節(jié)點(diǎn)厅贪,并且逆轉(zhuǎn)之后怎么獲取正確的原有下一節(jié)點(diǎn)蠢护。
    先創(chuàng)建一個(gè)測(cè)試的方法入口并且定義好測(cè)試用的鏈表。

    public static void main(String[] args) {
        //1個(gè)
        Node head = new Node(1);
        System.out.println(head);
        System.out.println(reverse(head));
        //2個(gè)
        head = new Node(1);
        head.addToNext(new Node(2));
        System.out.println(head);
        System.out.println(reverse(head));
        //3個(gè)
        head = new Node(1);
        head.addToNext(new Node(2))
                .addToNext(new Node(3));
        System.out.println(head);
        System.out.println(reverse(head));
        //4個(gè)
        head = new Node(1);
        head.addToNext(new Node(2))
                .addToNext(new Node(3))
                .addToNext(new Node(4));
        System.out.println(head);
        System.out.println(reverse(head));
        //多個(gè)
        head = new Node(1);
        Node tempHead = head;
        for (int i = 2; i <= 15; i++) {
            head = head.addToNext(new Node(i));
        }
        System.out.println(tempHead);
        System.out.println(reverse(tempHead));
    }
    
    

    ·直接在原基礎(chǔ)鏈表上反轉(zhuǎn)
    操作:遍歷原有鏈表养涮,直接將其下一個(gè)節(jié)點(diǎn)引用反轉(zhuǎn)

    public static Node reverse(Node head) {
        Node curNode = null;
        Node afterNode = null;
        if (head == null) {
            return null;
        }
        if (head.hasNext()) {
            curNode = head.getNext();
        } else {
            return head; //假如只有一個(gè)節(jié)點(diǎn)葵硕,則不反轉(zhuǎn)
        }
        if (curNode.hasNext()) {
            afterNode = curNode.getNext();
        } else {
            curNode.setNext(head); //假如鏈表只有兩個(gè)節(jié)點(diǎn) 直接反轉(zhuǎn)引用
            head.setNext(null);
            return curNode;
        }
        //假如有3個(gè)及3個(gè)以上
        //先將第一個(gè)節(jié)點(diǎn)獨(dú)立,如果不獨(dú)立則這個(gè)節(jié)點(diǎn)將永遠(yuǎn)指向原鏈表中的第二個(gè)節(jié)點(diǎn)贯吓,則會(huì)成環(huán)懈凹。必須切斷引用。
        head.setNext(null);
        Node newHead = head;//作為尾節(jié)點(diǎn)
        while (afterNode.hasNext()) {
            curNode.setNext(newHead);
            newHead = curNode;
            curNode = afterNode;
            afterNode = afterNode.getNext();
        }
        curNode.setNext(newHead);
        afterNode.setNext(curNode);
        return afterNode;
    }
    

執(zhí)行結(jié)果:


WX20180715-022129@2x.png

方法還有別的并且這個(gè)方法也應(yīng)該是可以簡(jiǎn)化的,這個(gè)只是第一感覺(jué)寫(xiě)出來(lái)的悄谐,后續(xù)再更新......未完......

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末介评,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子爬舰,更是在濱河造成了極大的恐慌们陆,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洼专,死亡現(xiàn)場(chǎng)離奇詭異棒掠,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)屁商,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)烟很,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蜡镶,你說(shuō)我怎么就攤上這事雾袱。” “怎么了官还?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵芹橡,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我望伦,道長(zhǎng)林说,這世上最難降的妖魔是什么煎殷? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮腿箩,結(jié)果婚禮上豪直,老公的妹妹穿的比我還像新娘。我一直安慰自己珠移,他們只是感情好弓乙,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著钧惧,像睡著了一般暇韧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浓瞪,一...
    開(kāi)封第一講書(shū)人閱讀 52,682評(píng)論 1 312
  • 那天懈玻,我揣著相機(jī)與錄音,去河邊找鬼追逮。 笑死酪刀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钮孵。 我是一名探鬼主播骂倘,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼巴席!你這毒婦竟也來(lái)了历涝?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤漾唉,失蹤者是張志新(化名)和其女友劉穎荧库,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體赵刑,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡分衫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了般此。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚪战。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖铐懊,靈堂內(nèi)的尸體忽然破棺而出邀桑,到底是詐尸還是另有隱情,我是刑警寧澤科乎,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布壁畸,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏捏萍。R本人自食惡果不足惜太抓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望照弥。 院中可真熱鬧腻异,春花似錦、人聲如沸这揣。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)给赞。三九已至,卻和暖如春矫户,著一層夾襖步出監(jiān)牢的瞬間片迅,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工皆辽, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柑蛇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓驱闷,卻偏偏與公主長(zhǎng)得像耻台,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子空另,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Java經(jīng)典問(wèn)題算法大全 /*【程序1】 題目:古典問(wèn)題:有一對(duì)兔子盆耽,從出生后第3個(gè)月起每個(gè)月都生一對(duì)兔子,小兔子...
    趙宇_阿特奇閱讀 1,875評(píng)論 0 2
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法扼菠,類相關(guān)的語(yǔ)法摄杂,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法循榆,異常的語(yǔ)法析恢,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,665評(píng)論 18 399
  • 我總是抱怨著,抱怨自己總是白白忙碌著秧饮,也發(fā)自內(nèi)心的討厭著自己的生活映挂;總是驕傲著,覺(jué)得自己懷才不遇而內(nèi)心長(zhǎng)戚戚浦楣。我想...
    我的狐貍朋友閱讀 462評(píng)論 0 1
  • 一場(chǎng)急雨 擋住了回家的路 這會(huì)兒要出門(mén)的人 反而被攔在了家里 曠野中成千上萬(wàn)朵花 來(lái)不及收起它們的花瓣 有主人的小...
    Toomm閱讀 151評(píng)論 0 4
  • 入霾塵而嬉游兮袖肥,登崇阿以?shī)是椋?見(jiàn)高樓之聳立兮,觀人間之所營(yíng)振劳。 樹(shù)煙囪之巍峨兮椎组,吐毒霧于太清, 臨珠水之長(zhǎng)流兮历恐,見(jiàn)...
    潘蔚閱讀 262評(píng)論 0 6