第2張 第⑤節(jié)雙向鏈表

雙向鏈表哈蝇,也稱(chēng)為雙鏈表棺妓,是一種線性數(shù)據(jù)結(jié)構(gòu),與單向鏈表類(lèi)似炮赦,但它在每個(gè)節(jié)點(diǎn)中額外存儲(chǔ)了一個(gè)指針怜跑,這個(gè)指針指向該節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)。因此,在雙向鏈表中性芬,每個(gè)節(jié)點(diǎn)都有兩個(gè)鏈接域峡眶,一個(gè)指向前一個(gè)節(jié)點(diǎn)(prev或previous),另一個(gè)指向下一個(gè)節(jié)點(diǎn)(next)植锉。這樣的設(shè)計(jì)使得在鏈表中雙向遍歷成為可能辫樱,即可以從頭到尾或從尾到頭地遍歷鏈表。

雙向鏈表的主要特點(diǎn)包括:

  1. 雙向遍歷:由于每個(gè)節(jié)點(diǎn)都保存了其前后節(jié)點(diǎn)的引用俊庇,所以可以在鏈表中雙向移動(dòng)狮暑,這在某些應(yīng)用場(chǎng)景下非常有用,比如快速反向遍歷或高效地在鏈表中間插入和刪除節(jié)點(diǎn)辉饱。

  2. 高效插入和刪除:相比于單向鏈表搬男,雙向鏈表在插入和刪除操作時(shí)可以更快地調(diào)整指針。特別是對(duì)于需要在某個(gè)節(jié)點(diǎn)之后插入新節(jié)點(diǎn)或者刪除該節(jié)點(diǎn)的情況彭沼,雙向鏈表可以直接通過(guò)當(dāng)前節(jié)點(diǎn)訪問(wèn)其前驅(qū)節(jié)點(diǎn)缔逛,無(wú)需從頭開(kāi)始遍歷。

  3. 內(nèi)存消耗:由于每個(gè)節(jié)點(diǎn)多了一個(gè)指針溜腐,雙向鏈表相比單向鏈表會(huì)占用更多的內(nèi)存空間。

  4. 頭部和尾部的標(biāo)識(shí):雙向鏈表可以很容易地維護(hù)對(duì)頭節(jié)點(diǎn)和尾節(jié)點(diǎn)的引用瓜喇,這在實(shí)現(xiàn)隊(duì)列等數(shù)據(jù)結(jié)構(gòu)時(shí)特別有用挺益。

結(jié)構(gòu)示例:

一個(gè)簡(jiǎn)單的雙向鏈表節(jié)點(diǎn)結(jié)構(gòu)可以定義如下:

class Node {
    int data; // 數(shù)據(jù)域
    Node prev; // 指向前一個(gè)節(jié)點(diǎn)的指針
    Node next; // 指向下一個(gè)節(jié)點(diǎn)的指針
}
雙向鏈表.png

在雙向鏈表中,通常還會(huì)有一個(gè)表示鏈表本身的類(lèi)乘寒,它包含對(duì)頭節(jié)點(diǎn)和可能的尾節(jié)點(diǎn)的引用望众,以及實(shí)現(xiàn)各種鏈表操作的方法,如添加伞辛、刪除烂翰、查找等。

應(yīng)用場(chǎng)景:

  • 實(shí)現(xiàn)LRU緩存:雙向鏈表結(jié)合哈希表可以高效地實(shí)現(xiàn)最近最少使用(LRU)緩存策略蚤氏。
  • undo/redo功能:在文本編輯器或圖形編輯軟件中甘耿,雙向鏈表可以用來(lái)高效地支持撤銷(xiāo)/重做操作。
  • 雙向隊(duì)列(deque):雙向鏈表自然適合實(shí)現(xiàn)允許兩端插入和刪除的隊(duì)列竿滨。

總之佳恬,雙向鏈表通過(guò)犧牲一定的內(nèi)存空間,換取了在特定操作上的效率提升和功能靈活性于游,是解決某些問(wèn)題時(shí)的理想選擇毁葱。

示例解析:

package com.dongf.chapter;

public class Node {

    int id;
    String name;
    int score;
    Node prev;
    Node next;

    public Node(int id, String name, int score) {
        this.id = id;
        this.name = name;
        this.score = score;
    }
}

Image00482.png
package com.dongf.chapter;

public class DoublyLinkedList {

    Node head;
    Node tail;

    public void append(int id, String name, int score) {
        Node newNode = new Node(id, name, score);
        if (head == null) {
            head = tail = newNode;
        } else {
            tail.next = newNode;
            newNode.prev = tail;
            tail = newNode;
        }
    }

    public void deleteById(int id) {
        Node current = head;
        while (current != null) {
            if (current.id == id) {
                if (current.prev != null) {
                    current.prev.next = current.next;
                } else {
                    head = current.next;
                }
                if (current.next != null) {
                    current.next.prev = current.prev;
                } else {
                    tail = current.prev;
                }
                return;
            }
            current = current.next;
        }
    }

    public void updateById(int id, int newScore) {
        Node current = head;
        while (current != null) {
            if (current.id == id) {
                current.score = newScore;
                return;
            }
            current = current.next;
        }
    }

    public Node findById(int id) {
        Node current = head;
        while (current != null) {
            if (current.id == id) {
                return current;
            }
            current = current.next;
        }
        return null; // 如果沒(méi)找到返回null
    }

    public void printList() {
        Node current = head;
        while (current != null) {
            System.out.println("ID: " + current.id + ", Name: " + current.name + ", Score: " + current.score);
            current = current.next;
        }
    }
}
Image00483.png
Image00484.png
Image00485.png
Image00486.png
package com.dongf.chapter;

public class DoublyLinkedListMain {

    public static void main(String[] args) {
        DoublyLinkedList list = new DoublyLinkedList();

        // 添加數(shù)據(jù)
        list.append(1, "張偉", 90);
        list.append(2, "李華", 88);
        list.append(3, "王芳", 92);
        list.append(4, "趙六", 76);
        list.append(5, "劉洋", 64);

        // 打印鏈表
        System.out.println("初始鏈表:");
        list.printList();

        // 更新張偉的成績(jī)?yōu)?3
        list.updateById(1, 93);
        System.out.println("\n更新張偉成績(jī)后的鏈表:");
        list.printList();

        // 刪除ID為4的節(jié)點(diǎn)
        list.deleteById(4);
        System.out.println("\n刪除ID為4的節(jié)點(diǎn)后的鏈表:");
        list.printList();

        // 查詢(xún)ID為3的節(jié)點(diǎn)
        Node foundNode = list.findById(3);
        if (foundNode != null) {
            System.out.println("\n找到了節(jié)點(diǎn):" + foundNode.name);
        } else {
            System.out.println("\n未找到指定ID的節(jié)點(diǎn)");
        }
    }
}

Image00487.png
Image00488.png

這段代碼定義了一個(gè)Node類(lèi)用于表示鏈表中的每個(gè)元素,以及一個(gè)DoublyLinkedList類(lèi)贰剥,實(shí)現(xiàn)了添加倾剿、刪除、更新和查詢(xún)節(jié)點(diǎn)的方法蚌成。在main方法中前痘,我們創(chuàng)建了一個(gè)雙向鏈表實(shí)例凛捏,執(zhí)行了增刪改查操作,并打印了相應(yīng)的結(jié)果际度。

?著作權(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)容