數(shù)據(jù)結(jié)構(gòu)---鏈表

1.鏈表基礎(chǔ)

  • 鏈表是數(shù)據(jù)結(jié)構(gòu)中另一種最基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)破花,數(shù)組需要開辟一段連續(xù)的存儲空間渊迁,所以在初始化的時(shí)候需要指定大小跨新,而鏈表并不需要指定大小,只要有足夠的空間都可以不斷地添加元素
  • 鏈表適合于增刪比較頻繁的數(shù)據(jù)蛆挫,而數(shù)據(jù)更適用于改動少赃承,查詢操作頻繁的情況,在根據(jù)索引查詢的時(shí)候可以快速定位
  • 鏈表不存在存儲空間不足的情況(除物理分配內(nèi)存不足)悴侵,而java中也有由鏈表為底層數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)瞧剖,支持泛型,即LinkedList(雙向鏈表)
  • 根據(jù)鏈表在本文實(shí)現(xiàn)一個單向鏈表可免,模擬LinkedList方法實(shí)現(xiàn)

2.實(shí)現(xiàn)

2.1.定義節(jié)點(diǎn)

  • 定義一個私有內(nèi)部類抓于,代表鏈表中的每一個節(jié)點(diǎn),而每一個結(jié)點(diǎn)中又定義下一個節(jié)點(diǎn)浇借,以替代指針捉撮,同時(shí)使每個節(jié)點(diǎn)連接起來。
public class LinkedList<E> {

    private class Node {
        public E e;
        public Node next;

        public Node(E e, Node next) {
            this.e = e;
            this.next = next;
        }

        public Node(E e) {  this(e, null);   }

        public Node() {    this(null, null); }

        @Override
        public String toString() {   return e.toString();  }
    }

    //鏈表頭
    private Node dummyHead;
    private int size;

    public LinkedList() {
        //虛擬頭節(jié)點(diǎn)指向真正的頭節(jié)點(diǎn)
        dummyHead = new Node(null, null);
        size = 0;
    }

    /**
     * 獲取鏈表中的元素個數(shù)
     * @return :
     */
    public int getSize() {   return size;  }

    /**
     * 當(dāng)前鏈表是否為空
     * @return :
     */
    public boolean isEmpty() {  return size == 0; }

采用設(shè)立一個虛擬頭節(jié)點(diǎn)妇垢,這樣就不要單獨(dú)處理頭節(jié)點(diǎn)巾遭,即初始化時(shí),初始一個空結(jié)點(diǎn)闯估,而而這個虛擬頭節(jié)點(diǎn)指向存儲的第一個非空結(jié)點(diǎn)灼舍。

2.2.添加一個新節(jié)點(diǎn)

  • 新添一個節(jié)點(diǎn),需要找到新添節(jié)點(diǎn)位置的前一個節(jié)點(diǎn)涨薪,使前一個節(jié)點(diǎn)的指針指向新添加的節(jié)點(diǎn)片仿,而前一個節(jié)點(diǎn)原來指向的節(jié)點(diǎn),變成新添加節(jié)點(diǎn)指向的節(jié)點(diǎn)
   /**
     * 在鏈表的index(0-based)位置添加新元素e
     * @param index :插入鏈表新元素的索引位置
     */
    public void add(int index, E e) {
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("Add failed. Illegal index");
        }
        //代表待添加節(jié)點(diǎn)索引的上一個節(jié)點(diǎn)尤辱,初始指向虛擬頭節(jié)點(diǎn)
        Node prev = dummyHead;
        //找到要插入位置的上一個元素(前結(jié)點(diǎn))
        for (int i = 0; i < index; i++) {
            prev = prev.next;
        }

        //將前結(jié)點(diǎn)的next結(jié)點(diǎn)當(dāng)作新結(jié)點(diǎn)的next,再將新結(jié)點(diǎn)作為前結(jié)點(diǎn)的next實(shí)現(xiàn)插入
        prev.next = new Node(e, prev.next);
        size++;
    }

    /**
     * 向鏈表中添加元素:
     * 在鏈表頭添加新元素砂豌,新元素索引指向當(dāng)前鏈表頭,當(dāng)前鏈表頭指針指向新添加元素
     * @param e :
     */
    public void addFirst(E e) {   add(0, e);   }

    /**
     * 在鏈表末尾添加一個新元素e
     */
    public void addLast(E e) {  add(size, e); }

鏈表添加節(jié)點(diǎn).png

2.3.改和查的方法

 /**
     * 獲取鏈表的第index(0-based)位置的元素e
     * @param index :獲取鏈表元素的索引位置
     * @return :該索引的元素
     */
    public E get(int index) {
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("Get failed. Illegal index");
        }
        //從頭元素(頭結(jié)點(diǎn))開始
        Node cur = dummyHead.next;
        //獲取第index位置結(jié)點(diǎn)
        for (int i = 0; i < index; i++) {
            cur = cur.next;
        }
        return cur.e;
    }

    /**
     * 獲取鏈表中第一個元素(頭節(jié)點(diǎn)元素)
     * @return :dummyHead.next.e; 
     */
    public E getFirst() {     return get(0);  }

    /**
     * 獲取鏈表中最后一個位置的元素
     * @return :
     */
    public E getLast() { return get(size - 1);  }

    /**
     * 修改鏈表中第index(0-based)位置的元素
     * 在鏈表中不是一個常用的操作光督,練習(xí)用
     */
    public void set(int index, E e) {
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("Get failed. Illegal index");
        }
        //從頭元素(頭結(jié)點(diǎn))開始
        Node cur = dummyHead.next;
        //獲取第index位置結(jié)點(diǎn)
        for (int i = 0; i < index; i++) {
            cur = cur.next;
        }
        cur.e = e;
    }

    /**
     * 該鏈表中是否存在該元素
     * @param e :
     * @return :
     */
    public boolean contains(E e) {
        Node cur = dummyHead.next;
        while (cur != null) {
            if (cur.e.equals(e)) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

2.4.刪除方法

    /**
     * 刪除鏈表中index(0-based)位置的元素阳距,并返回該元素:將刪除節(jié)點(diǎn)的next結(jié)點(diǎn)代替成刪除節(jié)點(diǎn)的位置
     * @param index :刪除節(jié)點(diǎn)的索引
     * @return :刪除節(jié)點(diǎn)的元素
     */
    public E remove(int index) {
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("Get failed. Illegal index");
        }
        //從虛擬頭節(jié)點(diǎn)開始
        Node prev = dummyHead;
        //獲取第index位置結(jié)點(diǎn)的上一個結(jié)點(diǎn)(前結(jié)點(diǎn))
        for (int i = 0; i < index; i++) {
            prev = prev.next;
        }
        Node deleteNode = prev.next;
        prev.next = deleteNode.next;
        deleteNode.next = null;
        size--;
        return deleteNode.e;
    }

    /**
     * 刪除鏈表中第一個元素,并返回元素值
     * @return :
     */
    public E removeFirst() { return remove(0);  }

    /**
     * 刪除結(jié)點(diǎn)中最后一個元素结借,并返回元素值
     * @return :
     */
    public E removeLast() {  return remove(size - 1);  }

2.5.重寫toString方法

    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();
        Node cur = dummyHead.next;
        while (cur != null) {
            str.append(cur + "-->");
            cur = cur.next;
        }
        str.append("NULL");
        return str.toString();
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末筐摘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子船老,更是在濱河造成了極大的恐慌咖熟,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柳畔,死亡現(xiàn)場離奇詭異馍管,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)薪韩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門确沸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捌锭,“玉大人,你說我怎么就攤上這事罗捎」矍” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵桨菜,是天一觀的道長豁状。 經(jīng)常有香客問我,道長倒得,這世上最難降的妖魔是什么替蔬? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮屎暇,結(jié)果婚禮上承桥,老公的妹妹穿的比我還像新娘。我一直安慰自己根悼,他們只是感情好凶异,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挤巡,像睡著了一般剩彬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上矿卑,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天喉恋,我揣著相機(jī)與錄音,去河邊找鬼母廷。 笑死轻黑,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的琴昆。 我是一名探鬼主播氓鄙,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼业舍!你這毒婦竟也來了抖拦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤舷暮,失蹤者是張志新(化名)和其女友劉穎态罪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體下面,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡复颈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诸狭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片券膀。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡君纫,死狀恐怖驯遇,靈堂內(nèi)的尸體忽然破棺而出芹彬,到底是詐尸還是另有隱情,我是刑警寧澤叉庐,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布舒帮,位于F島的核電站,受9級特大地震影響陡叠,放射性物質(zhì)發(fā)生泄漏玩郊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一枉阵、第九天 我趴在偏房一處隱蔽的房頂上張望译红。 院中可真熱鬧,春花似錦兴溜、人聲如沸侦厚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刨沦。三九已至霜瘪,卻和暖如春羞秤,著一層夾襖步出監(jiān)牢的瞬間橡淑,已是汗流浹背兆龙。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工江解, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留萎胰,地道東北人默辨。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓货岭,卻偏偏與公主長得像忘古,于是被迫代替她去往敵國和親讳癌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

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