數(shù)據(jù)結(jié)構(gòu)之雙向鏈表(java版)

記得在一個公司面試上有一道題备典,寫一個雙向鏈表异旧,包含鏈表的基本操作,插入提佣,刪除吮蛹,獲取長度等操作,由于時間匆忙拌屏,代碼寫的比較亂潮针,連自己都沒眼看了,后來細想自己從來都沒有細心的寫過數(shù)據(jù)結(jié)構(gòu)倚喂,總覺得只要原理明白了就萬事大吉了每篷,事實證明,理論和實踐還是有很大差距的务唐。
水平有限雳攘,如果有錯誤,還請不吝賜教

定義一個內(nèi)部類Node用于存儲節(jié)點元素

class Node {
     private Node previous;//前驅(qū)節(jié)點
     private Node next;//后繼節(jié)點
     private E e;//泛型元素值
     public Node(Node previous, Node next, E e) {
         this.previous = previous;
         this.next = next;
         this.e = e;
    }

雙向鏈表的關(guān)鍵在于節(jié)點指針的轉(zhuǎn)移

下面以removeElement(E value)為例簡單介紹

    public void removeElement(E value){
        Node index=this.first;//創(chuàng)建index節(jié)點指向first節(jié)點
        while(index!=null){
            if(index.e==value)break;
            index=index.next;
        }//while循環(huán)用于遍歷整個鏈表來獲取指向要刪除的節(jié)點指針
        index.previous.next=index.next;
        index.next.previous=index.previous;
        length--;
    }

index.previous表示要刪除節(jié)點的前驅(qū)節(jié)點
index.previous.next=index.next;意思是將前驅(qū)節(jié)點的后項指針指向要刪除節(jié)點的后繼節(jié)點
同理index.next表示要刪除節(jié)點的后繼節(jié)點
index.next.previous=index.previous;意思是將后繼節(jié)點的前向指針指向要刪除節(jié)點的前驅(qū)節(jié)點
可能有點繞枫笛,簡單畫個鏈表結(jié)構(gòu)圖就可以很明了了

insertNext(E baseElement,E value)insertPrevious(E baseElement,E value)同理吨灭,這里不再贅述

DoubleLinkedList包含兩個節(jié)點指針(偽指針,java中沒有指針的概念)first和last刑巧,分別指向鏈表的第一個元素和最后一個元素

整體代碼

public class DoubleLinkedList<E> {
    private Node first;//指向第一個元素
    private Node last;//指向最后一個元素
    private int length=0;//鏈表長度
    class Node {
        private Node previous;
        private Node next;
        private E e;

        public Node(Node previous, Node next, E e) {
            this.previous = previous;
            this.next = next;
            this.e = e;
        }
    }
    /***
     * 向頭節(jié)點添加元素喧兄,節(jié)點結(jié)構(gòu)對外應(yīng)該是不可見的,所以這里只傳遞一個泛型的值e
     */
    public void addFirst(E e) {
        if (first == null) {//鏈表為空判斷
            Node node = new Node(null, null, e);//創(chuàng)建一個新的節(jié)點啊楚,前驅(qū)和后繼都為空
            this.first = node;
            this.last=node;//將first和last指針指向鏈表的第一個元素
            length++;//鏈表長度自增一吠冤,下同
        }else{
            Node node=new Node(null,first,e);//鏈表不為空創(chuàng)建一個前驅(qū)為空,后繼為當前first節(jié)點的節(jié)點恭理,值為傳入的參數(shù)e
            this.first.previous=node;//當前first的前驅(qū)設(shè)置為node
            this.first=node;//將first指針指向新節(jié)點
            length++;
        }
    }
/***
*addLast同addFirst
*/
    public void addLast(E e) {
        if (last == null) {
            Node node = new Node(null, null, e);
            this.first = node;
            this.last=node;
            length++;
        }else{
            Node node=new Node(last,null,e);
            this.last.next=node;
            this.last=node;
            length++;
        }
    }
    public void insertPrevious(E baseElement,E value){
        Node index=this.first;
        while(index!=null){
            if(index.e==baseElement)break;
            index=index.next;
        }
        Node insertValue=new Node(index.previous,index,value);
        index.previous.next=insertValue;
        index.previous=insertValue;
        length++;
    }
    public void insertNext(E baseElement,E value){
        Node index=this.first;
        while(index!=null){
            if(index.e==baseElement)break;
            index=index.next;
        }
        Node insertValue=new Node(index,index.next,value);
        index.next.previous=insertValue;
        index.next=insertValue;
        length++;
    }
    public void removeElement(E value){
        Node index=this.first;
        while(index!=null){
            if(index.e==value)break;
            index=index.next;
        }
        index.previous.next=index.next;
        index.next.previous=index.previous;
        length--;
    }
    public int getLength(){
        return length;
    }
    @Override
    public String toString() {
        StringBuffer sb=new StringBuffer();
        Node current=this.first;
        while(current!=null){
            sb.append(current.e+"->");
            current=current.next;
        }
        return sb.toString();
    }
    public static void main(String[] args) {
        DoubleLinkedList<String> list=new DoubleLinkedList<>();
        list.addLast("value1");
        list.addLast("value2");
        list.addLast("value3");
        list.addLast("value4");
        list.addFirst("value0");
        list.insertPrevious("value3","insertValue");
        list.insertNext("value3","insertValue2");
        System.out.println(list.toString());
        System.out.println("鏈表的長度是"+list.getLength());
        list.removeElement("value3");
        System.out.println(list.toString());
        System.out.println("鏈表的長度是"+list.getLength());
    }
}

如果不太了解雙向鏈表的結(jié)構(gòu)可以在紙上畫出每個Node以及指向關(guān)系

更多關(guān)于java的文章請戳這里:(您的留言意見是對我最大的支持)

我的文章列表
Email:sxh13208803520@gmail.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拯辙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涯保,老刑警劉巖诉濒,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異夕春,居然都是意外死亡未荒,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門及志,熙熙樓的掌柜王于貴愁眉苦臉地迎上來片排,“玉大人,你說我怎么就攤上這事速侈÷使眩” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵锌畸,是天一觀的道長勇劣。 經(jīng)常有香客問我,道長潭枣,這世上最難降的妖魔是什么比默? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮盆犁,結(jié)果婚禮上命咐,老公的妹妹穿的比我還像新娘。我一直安慰自己谐岁,他們只是感情好醋奠,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著伊佃,像睡著了一般窜司。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上航揉,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天塞祈,我揣著相機與錄音,去河邊找鬼帅涂。 笑死议薪,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的媳友。 我是一名探鬼主播斯议,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼醇锚!你這毒婦竟也來了哼御?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎艇搀,沒想到半個月后尿扯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡焰雕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了芳杏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矩屁。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖爵赵,靈堂內(nèi)的尸體忽然破棺而出吝秕,到底是詐尸還是另有隱情,我是刑警寧澤空幻,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布烁峭,位于F島的核電站,受9級特大地震影響秕铛,放射性物質(zhì)發(fā)生泄漏约郁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一但两、第九天 我趴在偏房一處隱蔽的房頂上張望鬓梅。 院中可真熱鬧,春花似錦谨湘、人聲如沸绽快。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坊罢。三九已至,卻和暖如春擅耽,著一層夾襖步出監(jiān)牢的瞬間活孩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工秫筏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留诱鞠,地道東北人。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓这敬,卻偏偏與公主長得像航夺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子崔涂,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

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