国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn)

這篇具有很好參考價值的文章主要介紹了[Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1.ArrayList的缺點

上篇文章我們已經(jīng)對順序表進行了實現(xiàn),并且對ArrayList進行了使用,我們知道ArrayList底層是使用數(shù)組實現(xiàn)的.
由于其底層是一段連續(xù)空間,當(dāng)在ArrayList任意位置插入或者刪除元素時,就需要將后序元素整體往前或者往后搬移,時間復(fù)雜度為O(n),效率比較低,因此ArrayList不適合做任意位置插入和刪除比較多的場景。因此:java集合中又引入了LinkedList,即鏈表結(jié)構(gòu)。

2.鏈表

2.1 鏈表的概念與結(jié)構(gòu)

鏈表是一種物理存儲結(jié)構(gòu)上非連續(xù)存儲結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的引用鏈接次序實現(xiàn)的.就像一列動車一樣.
[Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn),Collection與數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),鏈表
[Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn),Collection與數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),鏈表
通過上圖我們可以看到,一個鏈表中有一節(jié)一節(jié)的"車廂",還有中間的"鏈條".我們稱每一節(jié)"車廂"為結(jié)點,我們可以看到每一個結(jié)點中有下一個結(jié)點的地址,鏈表就是通過存儲節(jié)點的地址來連接起來的,還有該結(jié)點的值.上面就是我們需要重點掌握的一種鏈表類型,叫做單向無頭非循環(huán)鏈表.其實鏈表還有好多類型,下面我們來展示.

2.2 鏈表的類型

鏈表有以下幾種性質(zhì):有頭/無頭,單向/雙向,循環(huán)/非循環(huán)

  1. 有頭/無頭
    [Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn),Collection與數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),鏈表
    [Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn),Collection與數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),鏈表
    它們的區(qū)別就是,有頭鏈表的head永遠指向一個固定的結(jié)點,而無頭鏈表的head永遠在改變.
  2. 單向/雙向
    [Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn),Collection與數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),鏈表

[Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn),Collection與數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),鏈表
3. 循環(huán)/非循環(huán)
[Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn),Collection與數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),鏈表
[Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn),Collection與數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),鏈表
上面幾種性質(zhì)排列組合可以得到許多中鏈表的類型,這里我們重點掌握2中即可,一種是單向無頭非循環(huán),它在筆面試中經(jīng)常出現(xiàn),另一種是是無頭雙向非循環(huán)鏈表,Java中的LinkedList底層就是通過它來實現(xiàn)的.

3. 單向無頭非循環(huán)鏈表實現(xiàn)

下面是要實現(xiàn)的接口,即鏈表中的常用方法:

public interface ILinkedList {
    void addFirst(int data);
    //尾插法
    void addLast(int data);
    //任意位置插入,第一個數(shù)據(jù)節(jié)點為0號下標
    void addIndex(int index,int data);
    //查找是否包含關(guān)鍵字key是否在單鏈表當(dāng)中
    boolean contains(int key);
    //刪除第一次出現(xiàn)關(guān)鍵字為key的節(jié)點
    void remove(int key);
    //刪除所有值為key的節(jié)點
    void removeAllKey(int key);
    //得到單鏈表的長度
    int size();
    //清空鏈表
    void clear() ;
    //打印鏈表
    void display();

}

下面我們來實現(xiàn)這些方法:

public class MyLinkedList implements ILinkedList {
    static class Node{
        public int val;
        public Node next = null;
        public Node(int val) {
            this.val = val;
        }
    }
    public Node head = null;

    /**
     * 創(chuàng)建默認鏈表
     */
    public void createDeafultLinkedList(){
        Node node = new Node(23);
        this.head = node;
        Node node1 = new Node(34);
        node.next = node1;
        Node node2 = new Node(45);
        node1.next = node2;
        Node node3 = new Node(56);
        node2.next = node3;
        Node node4 = new Node(67);
        node3.next = node4;
    }

    /**
     * 在鏈表頭部添加新的結(jié)點
     * @param data
     */
    @Override
    public void addFirst(int data) {
        Node node = new Node(data);
//        if(head == null){
//            head = node;
//        }else {
//            node.next = head;
//            head = node;
//        }
        //上面的代碼其實沒必要驗證鏈表是否為空,head為null賦值過去還是null
        node.next = this.head;
        this.head = node;
    }

    /**
     * 在尾部添加新的結(jié)點
     * @param data
     */
    @Override
    public void addLast(int data) {
        Node node = new Node(data);
        Node cur = this.head;
        if (this.head == null){
            this.head = node;
        }else {
            while (cur.next != null){
                cur = cur.next;
            }
            cur.next = node;
        }
    }

    /**
     * 在指定位置添加結(jié)點
     * @param index
     * @param data
     */
    @Override
    public void addIndex(int index, int data) {
        if (index > size() || index < 0){
            throw new IndexExeption("下標有誤");
        }
        Node node = new Node(data);
        if (this.head == null){
            this.head = node;
            return;//記得返回,不然會執(zhí)行中間插入的代碼
        }
        if (index == 0){//在鏈表頭添加
            addFirst(node.val);
            return;
        }
        if (index == size()){//在鏈表尾部添加
            addLast(node.val);
            return;
        }
        //在中部添加
        Node cur = this.head;
        int count = 0;
        while (count != index-1){//尋找cur的前一個結(jié)點
            cur = cur.next;
            count++;
        }
        node.next = cur.next;
        cur.next = node;
    }

    /**
     * 檢測鏈表中是否含有指定的值
     * @param key
     * @return
     */
    @Override
    public boolean contains(int key) {
        Node cur = this.head;
        while (cur != null){//先遍歷鏈表
            if(cur.val == key){//在遍歷的過程中如果等于,返回true
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    /**
     * 移除遇到的第一個值為key的元素
     * @param key
     */
    @Override
    public void remove(int key) {
        if (this.head == null){
            return;
        }
        if (head.val == key){
            head = head.next;
            return;
        }
        Node cur = findPreNode(key);//需要找到前一個結(jié)點才可以刪除
        if (cur == null){//沒找到要刪除的結(jié)點
            return;
        }
        cur.next = cur.next.next;
    }
    private Node findPreNode(int key){//找到要刪除結(jié)點的前一個結(jié)點
        Node cur = this.head;
        while (cur.next != null){//這里必須寫成next不等于null,否則下面可能會出現(xiàn)空指針異常
            if (cur.next.val == key){
                return cur;
            }
            cur = cur.next;
        }
        return null;
    }

    /**
     * 移除所有符合值為key的結(jié)點
     * @param key
     */

    @Override
    public void removeAllKey(int key) {
        if (this.head == null){
            return;
        }
        Node pre = this.head;
        Node cur = this.head.next;
        //先不要管頭結(jié)點,先刪中間的
        while(cur != null){
            if (cur.val == key){
                pre.next = cur.next;
            }else {
                pre = pre.next;//若該結(jié)點不是要刪除的結(jié)點,pre往后走
            }
            cur = cur.next;
        }
        //所有的都刪完了,刪除頭結(jié)點
        if (head.val == key){
            head = head.next;
        }
    }

    /**
     * 計算鏈表大小
     * @return
     */
    @Override
    public int size() {
        int count = 0;
        Node cur = this.head;
        while (cur != null){
            count++;
            cur = cur.next;
        }
        return count;
    }

    /**
     * 清空鏈表
     */
    @Override
    public void clear() {
        head = null;//為被引用的結(jié)點會被JWM回收
    }

    /**
     * 打印鏈表
     */
    @Override
    public void display() {
        Node cur = this.head;
        while (cur != null){
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }

    /**
     * 從指定位置開始打印鏈表
     * @param node
     */
    public void display(Node node) {
        Node cur = node;
        while (cur != null){
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }

}

上面有幾個問題需要注意

  1. 在中間插入元素的時候先要進行后鏈接,在進行前鏈接,如果先進行前鏈接,cur的下一個結(jié)點的地址就會丟失
  2. 在刪除所有值為key的結(jié)點的時候,先刪除head后符合條件的結(jié)點最后再處理head.

下面是對上述問題的動態(tài)演示:

[插入結(jié)點錯誤演示]

插入中間節(jié)點(錯誤)

[插入結(jié)點正確演示]

插入中間結(jié)點(正確)

[刪除所有key結(jié)點]

刪除所有key結(jié)點

下面我們對上述實現(xiàn)的方法進行測試:

**
 * 開始測試
 */
public class Test {
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.createDeafultLinkedList();
        myLinkedList.addFirst(11);
        myLinkedList.addLast(88);
        myLinkedList.display();
        System.out.println(myLinkedList.size());
        myLinkedList.addIndex(2,33);
        myLinkedList.display();
        System.out.println(myLinkedList.contains(11));
        System.out.println(myLinkedList.contains(12));
        myLinkedList.addIndex(1,23);
        myLinkedList.addIndex(1,23);
        myLinkedList.addIndex(1,23);
        myLinkedList.display();
        myLinkedList.remove(23);
        myLinkedList.display();
        myLinkedList.removeAllKey(23);
        myLinkedList.display();
        myLinkedList.clear();
        myLinkedList.display();
    }
}

測試結(jié)果:
[Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn),Collection與數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),鏈表文章來源地址http://www.zghlxwxcb.cn/news/detail-858484.html

到了這里,關(guān)于[Collection與數(shù)據(jù)結(jié)構(gòu)] 鏈表與LinkedList (一):鏈表概述與單向無頭非循環(huán)鏈表實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu)—LinkedList與鏈表

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

    目錄 一、鏈表 1.?鏈表的概念及結(jié)構(gòu) 1. 單向或者雙向 2. 帶頭或者不帶頭 3. 循環(huán)或者非循環(huán) 二.LinkedList的使用 ?1.LinkedList概念及結(jié)構(gòu) 2. LinkedList的構(gòu)造 3.?LinkedList的方法 三. ArrayList和LinkedList的區(qū)別 ? ????????鏈表是一種 物理存儲結(jié)構(gòu)上非連續(xù) 存儲結(jié)構(gòu),數(shù)據(jù)元素的 邏輯

    2024年02月04日
    瀏覽(26)
  • LinkedList數(shù)據(jù)結(jié)構(gòu)鏈表

    LinkedList 在Java中是一個實現(xiàn)了 List 和 Deque 接口的雙向鏈表。它允許我們在列表的兩端添加或刪除元素,同時也支持在列表中間插入或移除元素。在分析 LinkedList 之前,需要理解鏈表這種數(shù)據(jù)結(jié)構(gòu): 鏈表 :鏈表是一種動態(tài)數(shù)據(jù)結(jié)構(gòu),由一系列節(jié)點組成,每個節(jié)點包含數(shù)據(jù)部分

    2024年02月20日
    瀏覽(19)
  • 【C/C++數(shù)據(jù)結(jié)構(gòu)】鏈表與快慢指針

    【C/C++數(shù)據(jù)結(jié)構(gòu)】鏈表與快慢指針

    目錄 一、單鏈表 二、雙向循環(huán)鏈表 三、判斷鏈表是否帶環(huán) 四、鏈表的回文結(jié)構(gòu)判斷 五、復(fù)制帶隨機指針的鏈表 優(yōu)點 :頭部增刪效率高,動態(tài)存儲無空間浪費 缺點 :尾部增刪、遍歷效率低,不支持隨機訪問節(jié)點 頭結(jié)點 :單鏈表頭結(jié)點可有可無,帶頭結(jié)點更方便進行初始

    2024年02月16日
    瀏覽(436)
  • 【數(shù)據(jù)結(jié)構(gòu)二】鏈表和LinkedList詳解

    【數(shù)據(jù)結(jié)構(gòu)二】鏈表和LinkedList詳解

    目錄 鏈表和LinkedList ?1.鏈表的實現(xiàn) 2.LinkedList的使用 3.ArrayList和LinkedList的區(qū)別 4.鏈表OJ題訓(xùn)練 ? ? ? ? 當(dāng) 在 ArrayList 任意位置插入或者刪除元素時,就需要將后序元素整體往前或者往后 搬移,時間復(fù)雜度為 O(n) ,效率比較低,因此 ArrayList 不適合做任意位置插入和刪除比較多

    2024年01月20日
    瀏覽(41)
  • 【數(shù)據(jù)結(jié)構(gòu)】鏈表(單鏈表與雙鏈表實現(xiàn)+原理+源碼)

    【數(shù)據(jù)結(jié)構(gòu)】鏈表(單鏈表與雙鏈表實現(xiàn)+原理+源碼)

    博主介紹:?全網(wǎng)粉絲喜愛+、前后端領(lǐng)域優(yōu)質(zhì)創(chuàng)作者、本質(zhì)互聯(lián)網(wǎng)精神、堅持優(yōu)質(zhì)作品共享、掘金/騰訊云/阿里云等平臺優(yōu)質(zhì)作者、擅長前后端項目開發(fā)和畢業(yè)項目實戰(zhàn)?有需要可以聯(lián)系作者我哦! ??附上相關(guān)C語言版源碼講解?? ???? 精彩專欄推薦訂閱???? 不然下次找

    2024年01月24日
    瀏覽(638)
  • 【數(shù)據(jù)結(jié)構(gòu) | 入門】線性表與鏈表 (問題引入&實現(xiàn)&算法優(yōu)化)

    【數(shù)據(jù)結(jié)構(gòu) | 入門】線性表與鏈表 (問題引入&實現(xiàn)&算法優(yōu)化)

    ???♂? 個人主頁: @計算機魔術(shù)師 ????? 作者簡介:CSDN內(nèi)容合伙人,全棧領(lǐng)域優(yōu)質(zhì)創(chuàng)作者。 本文是浙大數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)筆記專欄 這里我們引入一個問題,最常見的多項式,我們?nèi)绾问褂镁幊虒⒍囗検奖硎境鰜砟兀?我們可以使用數(shù)組來表示,但是會隨著一個問題,如下圖底

    2024年01月21日
    瀏覽(129)
  • 數(shù)據(jù)結(jié)構(gòu)(Java實現(xiàn))LinkedList與鏈表(上)

    數(shù)據(jù)結(jié)構(gòu)(Java實現(xiàn))LinkedList與鏈表(上)

    鏈表 邏輯結(jié)構(gòu) 無頭單向非循環(huán)鏈表:結(jié)構(gòu)簡單,一般不會單獨用來存數(shù)據(jù)。實際中更多是作為其他數(shù)據(jù)結(jié)構(gòu)的子結(jié)構(gòu),如哈希桶、圖的鄰接表等等。 無頭雙向鏈表:在Java的集合框架庫中LinkedList底層實現(xiàn)就是無頭雙向循環(huán)鏈表。 鏈表的實現(xiàn) 創(chuàng)建一個鏈表 遍歷單鏈表 、 得到

    2024年02月11日
    瀏覽(30)
  • 數(shù)據(jù)結(jié)構(gòu)(Java實現(xiàn))LinkedList與鏈表(下)

    數(shù)據(jù)結(jié)構(gòu)(Java實現(xiàn))LinkedList與鏈表(下)

    ** ** 結(jié)論 讓一個指針從鏈表起始位置開始遍歷鏈表,同時讓一個指針從判環(huán)時相遇點的位置開始繞環(huán)運行,兩個指針都是每次均走一步,最終肯定會在入口點的位置相遇。 LinkedList的模擬實現(xiàn) 單個節(jié)點的實現(xiàn) 尾插 運行結(jié)果如下: 也可以暴力使用 全部代碼 MyLinkedList IndexOut

    2024年02月11日
    瀏覽(22)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法分析】反轉(zhuǎn)鏈表與順序表(內(nèi)含源碼,思路清晰)

    【數(shù)據(jù)結(jié)構(gòu)與算法分析】反轉(zhuǎn)鏈表與順序表(內(nèi)含源碼,思路清晰)

    ??順序表和鏈表都是數(shù)據(jù)結(jié)構(gòu)中常見的線性表。它們的主要區(qū)別在于 內(nèi)存管理方式不同 。 ??順序表(Array)是由一系列元素按照一定順序依次排列而成,它使用連續(xù)的內(nèi)存空間存儲數(shù)據(jù)。順序表使用一個數(shù)組來存儲數(shù)據(jù),數(shù)組中的每個元素都可以通過下標來訪問。順序

    2024年02月07日
    瀏覽(85)
  • 【數(shù)據(jù)結(jié)構(gòu)】_4.List接口實現(xiàn)類LinkedList與鏈表

    【數(shù)據(jù)結(jié)構(gòu)】_4.List接口實現(xiàn)類LinkedList與鏈表

    目錄 1.鏈表的結(jié)構(gòu)與特點 1.1 鏈表的結(jié)構(gòu): 1.2 鏈表的特點: 2. 不帶頭單鏈表的模擬實現(xiàn) 3. 單鏈表OJ 3.1 題目1:移除鏈表元素:? 3.2 題目2:反轉(zhuǎn)一個單鏈表 3.3 題目3:返回鏈表的中間結(jié)點 3.4 題目4:鏈表的倒數(shù)第k個結(jié)點 3.5 題目5:合并兩個有序鏈表 3.6 題目6:鏈表的回文結(jié)構(gòu)

    2024年02月15日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包