第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

1. 前言

我們今天要通過了解鏈表的原理來掌握鏈表這個(gè)重要的數(shù)據(jù)結(jié)構(gòu),隨后用我們了解到的鏈表的知識來重新認(rèn)識一下我們每天都要接觸的最常見的鏈表 java.util.LinkedList 類。

2. 數(shù)組的缺陷

數(shù)組作為我們最常見的通用數(shù)據(jù)結(jié)構(gòu),幾乎可以實(shí)現(xiàn)我們常見的所有數(shù)據(jù)結(jié)構(gòu)。然而,數(shù)組的特點(diǎn)決定了它的適用場景必然是有限的,比如占用空間大小固定,空間過小可能不能滿足數(shù)據(jù)量的要求,空間過大又會造成內(nèi)存資源的浪費(fèi),再比如數(shù)組的插入效率很低等等。
那有沒有一種插入效率很高,而且不需要頻繁擴(kuò)容的基本數(shù)據(jù)結(jié)構(gòu)呢?答案是肯定的,它就是 —— 鏈表。
圖片來源于網(wǎng)絡(luò),圖片版權(quán)歸屬原作者

3. 什么是鏈表

鏈表是一組鏈?zhǔn)浇Y(jié)構(gòu)的數(shù)據(jù)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都包含保存數(shù)據(jù)的部分,以及用來指向上一個(gè)或下一個(gè)節(jié)點(diǎn)位置的鏈接信息。鏈表是一種線性表,它可以靈活的根據(jù)數(shù)據(jù)大小來使用內(nèi)存空間,但是由于它在內(nèi)存中不是連續(xù)存儲的,所以根據(jù)角標(biāo)查詢的效率很低,同時(shí)由于每一個(gè)節(jié)點(diǎn)上除了數(shù)據(jù)信息還額外存儲了與其他節(jié)點(diǎn)的鏈接信息,所以對空間的占用也更大一些。

4. 單向鏈表

我們首先通過最簡單的鏈表 —— 單向鏈表來熟悉一下鏈表的結(jié)構(gòu)和存儲原理。
單鏈表的每一個(gè)節(jié)點(diǎn)我們稱之為 Node,都包含一個(gè)存儲數(shù)據(jù)的部分我們稱為之 data,還有一部分用來存儲下一個(gè)節(jié)點(diǎn)的地址我們稱之為 links。鏈表的第一個(gè)節(jié)點(diǎn)我們稱之為 head 頭節(jié)點(diǎn)。
圖片描述

5. 雙端鏈表

單向鏈表由于只記錄了自己的下一個(gè)節(jié)點(diǎn),所以它的訪問方向是單向的。如果我想在最后一個(gè)節(jié)點(diǎn)后添加元素,就需要從第一個(gè)節(jié)點(diǎn)開始挨個(gè)遍歷,很不方便,于是我們給鏈表的最后一個(gè)節(jié)點(diǎn)標(biāo)示為 tail 尾節(jié)點(diǎn),便于我們在最后一個(gè)節(jié)點(diǎn)插入元素的時(shí)候可以直接引用尾節(jié)點(diǎn),這就叫做雙端鏈表。

6. 雙向鏈表

前面講的單向鏈表和雙端鏈表其實(shí)主要是讓大家了解鏈表的存儲原理,實(shí)際我們使用最多的是雙向鏈表,雙向鏈表在單向鏈表的基礎(chǔ)上同時(shí)記錄了上一個(gè)節(jié)點(diǎn)和下一個(gè)節(jié)點(diǎn)兩個(gè)指針信息,遍歷更加方便。
Java 中對于雙向鏈表有現(xiàn)成的實(shí)現(xiàn),就是我們非常熟悉的 java.util.LinkedList。在源碼中我們可以看到 LinkedList 把節(jié)點(diǎn)定義成三個(gè)部分:元素、上一節(jié)點(diǎn)和下一節(jié)點(diǎn)。

其實(shí)鏈表的最大的魅力就是可以優(yōu)雅高效地插入數(shù)據(jù),它只需要在要插入的位置修改前后節(jié)點(diǎn)的指針就可以完成,完全不需要移動(dòng)其他的數(shù)據(jù)。LinkedList 源碼中是這樣實(shí)現(xiàn)的:

結(jié)合上圖,我們用動(dòng)圖來模擬實(shí)現(xiàn)一下 LinkedList 的 add 方法:

動(dòng)圖中的節(jié)點(diǎn)位置我故意擺放得很零散,就是為了突出這些節(jié)點(diǎn)在內(nèi)存中的位置并不是連續(xù)的,這也體現(xiàn)出了鏈表可以對內(nèi)存里這些零散角落高效利用的特點(diǎn)。

對于刪除操作,鏈表完全可以根據(jù)插入的逆操作來高效優(yōu)雅地完成。

7. 鏈表的優(yōu)缺點(diǎn)

鏈表的優(yōu)點(diǎn)是大小可變,插入和刪除的效率很高,缺點(diǎn)是只能通過順序指針訪問,查詢的效率較低。無圖無真相,我們結(jié)合圖片看一下他們分別是如何獲取指定元素的。先來看下基于數(shù)組的 ArrayList:
圖片描述
再來看下基于鏈表的 LinkedList:
圖片描述
對比基于數(shù)組的 ArrayList 和基于鏈表的 LinkedList 的 get (index i) 方法的實(shí)現(xiàn)就會發(fā)現(xiàn),鏈表需要遍歷才能返回想要的元素,所以效率才比較低下。知道了鏈表的這些特性,我們今后在使用這一數(shù)據(jù)結(jié)構(gòu)的時(shí)候就知道如何讓它在合適的時(shí)候發(fā)揮它的最大優(yōu)勢咯。

8. 小結(jié)

這一小節(jié)我們知道了鏈表是一種線性結(jié)構(gòu)的基本數(shù)據(jù)類型,可以分為單向鏈表、雙端鏈表、雙向鏈表等,內(nèi)部實(shí)現(xiàn)的原理都是在每一個(gè)節(jié)點(diǎn)上除了記錄數(shù)據(jù)外,還記錄了上一個(gè)或下一個(gè)節(jié)點(diǎn)的位置信息。它的特點(diǎn)是插入和刪除的效率很高,查詢的效率較低