Java之LinkedList實(shí)現(xiàn)原理

LinkedList數(shù)據(jù)結(jié)構(gòu)原理

LinkedList底層的數(shù)據(jù)結(jié)構(gòu)是基于雙向循環(huán)鏈表的爆哑,且頭結(jié)點(diǎn)中不存放數(shù)據(jù)洞难;


LinkedList構(gòu)造函數(shù)
transient int size = 0;
transient Link<E> voidLink;
private static final class Link<ET> {
    ET data;
    Link<ET> previous, next;
    Link(ET o, Link<ET> p, Link<ET> n) {
        data = o;
        previous = p;
        next = n;
   }
}
public LinkedList() {
      voidLink = new Link<E>(null, null, null);
      voidLink.previous = voidLink;
      voidLink.next = voidLink;
}

Link是LinkedList的靜態(tài)內(nèi)部類,可以看作節(jié)點(diǎn)類,data用來(lái)存放數(shù)據(jù)队贱,previous與next則分別存放前后節(jié)點(diǎn)的信息色冀;而構(gòu)造函數(shù)中實(shí)際上是作了對(duì)voidLink的初始化操作,也就是對(duì)頭指針的初始化操作柱嫌;
空鏈表的情況應(yīng)該是header節(jié)點(diǎn)的前一節(jié)點(diǎn)和后一節(jié)點(diǎn)均為null锋恬;

1.添加一個(gè)元素到鏈表尾部

public boolean add(E object) {
        return addLastImpl(object);
}

private boolean addLastImpl(E object) {
     Link<E> oldLast = voidLink.previous;
     Link<E> newLink = new Link<E>(object, oldLast, voidLink);
     voidLink.previous = newLink;
     oldLast.next = newLink;
     size++;
     modCount++;
     return true;
}

從源碼中可以看到,添加元素到鏈表尾實(shí)際上是新new了一個(gè)Link節(jié)點(diǎn)(newLink);
voidLink實(shí)際上是頭節(jié)點(diǎn)编丘,然后把頭節(jié)點(diǎn)的前結(jié)點(diǎn)指向newLink与学;把原尾結(jié)節(jié)oldLast的后結(jié)點(diǎn)指向newLink;

2.添加一個(gè)元素到鏈表指定位置

public void add(int location, E object) {
        if (location >= 0 && location <= size) {
            Link<E> link = voidLink;
            if (location < (size / 2)) {
                for (int i = 0; i <= location; i++) {
                    link = link.next;
                }
            } else {
                for (int i = size; i > location; i--) {
                    link = link.previous;
                }
            }
            Link<E> previous = link.previous;
            Link<E> newLink = new Link<E>(object, previous, link);
            previous.next = newLink;
            link.previous = newLink;
            size++;
            modCount++;
        } else {
            throw new IndexOutOfBoundsException();
        }
}

添加到鏈表指定位置嘉抓,會(huì)先遍歷索守,是順向迭代還是反向迭代,找到位置然后再同上添加元素的操作抑片,將節(jié)點(diǎn)指向修改正確卵佛;

3.刪除數(shù)據(jù)

public E remove(int location) {
        if (location >= 0 && location < size) {
            Link<E> link = voidLink;
            if (location < (size / 2)) {
                for (int i = 0; i <= location; i++) {
                    link = link.next;
                }
            } else {
                for (int i = size; i > location; i--) {
                    link = link.previous;
                }
            }
            Link<E> previous = link.previous;
            Link<E> next = link.next;
            previous.next = next;
            next.previous = previous;
            size--;
            modCount++;
            return link.data;
        }
        throw new IndexOutOfBoundsException();
    }

刪除的節(jié)點(diǎn)對(duì)象是由系統(tǒng)去gc回收的第股;

4.查找數(shù)據(jù)與修改數(shù)據(jù)
為了提高效率楚里,需要根據(jù)獲取的位置判斷是從頭還是從尾開(kāi)始遍歷

5.用LinkedList模似堆棧

addLastImpl(E object)
addFirst(E object)
removeFirstImpl()
removeLast()

在LinekList中封裝了上面四個(gè)方法腺毫,分別添加刪除鏈表頭尾庭砍,對(duì)鏈表的操作進(jìn)行一下封裝和限制就可以模擬堆椨褂眨或者隊(duì)列了芽狗;

public class Test5{
  public static void main(String[] args){
    Duilie dl = new Duilie();
    dl.myAdd("abc1);
    dl.myAdd("abc2);
    dl.myAdd("abc3);
    dl.myAdd("abc4);
    while(!dl.isNull()){
        System.out.println(dl.myGet());
    }
  }
}
class Duilie{
  private LinkedList link;
  public Duilie(){
    link = new LinkedList();
  }
  
  public void myAdd(Object obj){
     //添加到鏈表尾部
     link.addLast(obj);
  }

  public Object myGet(){
    //獲取頭部元素
    //  return link.removeFirst(); 模似隊(duì)列
    //獲取尾部元素
      return link.removeLast();  //模似堆棧
  }
  
   public boolean isNull(){
      return link.isEmpty();
   }
}

LinkedList總結(jié)
①數(shù)據(jù)存儲(chǔ)是基于雙向鏈表實(shí)現(xiàn)的喉前;
②插入數(shù)據(jù)很快令野。先是在雙向鏈表中找到要插入節(jié)點(diǎn)的位置index焰枢,找到之后蚓峦,再插入一個(gè)新節(jié)點(diǎn)。 雙向鏈表查找index位置的節(jié)點(diǎn)時(shí)医咨,有一個(gè)加速動(dòng)作:若index < 雙向鏈表長(zhǎng)度的1/2枫匾,則從前向后查找; 否則拟淮,從后向前查找干茉;
③刪除數(shù)據(jù)很快。先是在雙向鏈表中找到要插入節(jié)點(diǎn)的位置index很泊,找到之后角虫,進(jìn)行如下操作:node.previous.next = node.next;node.next.previous = node.previous;node = null ,查找節(jié)點(diǎn)過(guò)程和插入一樣委造;
④獲取數(shù)據(jù)很慢戳鹅,需要從頭節(jié)點(diǎn)進(jìn)行查找;
⑤遍歷數(shù)據(jù)很慢昏兆,每次獲取數(shù)據(jù)都需要從頭開(kāi)始枫虏;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子隶债,更是在濱河造成了極大的恐慌腾它,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件死讹,死亡現(xiàn)場(chǎng)離奇詭異瞒滴,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)赞警,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)妓忍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人愧旦,你說(shuō)我怎么就攤上這事世剖。” “怎么了笤虫?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵搁廓,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我耕皮,道長(zhǎng),這世上最難降的妖魔是什么蝙场? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任凌停,我火速辦了婚禮,結(jié)果婚禮上售滤,老公的妹妹穿的比我還像新娘罚拟。我一直安慰自己,他們只是感情好完箩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布赐俗。 她就那樣靜靜地躺著,像睡著了一般弊知。 火紅的嫁衣襯著肌膚如雪阻逮。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,482評(píng)論 1 302
  • 那天秩彤,我揣著相機(jī)與錄音叔扼,去河邊找鬼。 笑死漫雷,一個(gè)胖子當(dāng)著我的面吹牛瓜富,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播降盹,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼与柑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起价捧,我...
    開(kāi)封第一講書(shū)人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤丑念,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后干旧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體渠欺,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年椎眯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挠将。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡编整,死狀恐怖舔稀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情掌测,我是刑警寧澤内贮,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站汞斧,受9級(jí)特大地震影響夜郁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜粘勒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一竞端、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庙睡,春花似錦事富、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至啡邑,卻和暖如春贱勃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谣拣。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工募寨, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人森缠。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓拔鹰,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親贵涵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子列肢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

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