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

數(shù)據(jù)結(jié)構(gòu)與算法(三):單向鏈表

這篇具有很好參考價值的文章主要介紹了數(shù)據(jù)結(jié)構(gòu)與算法(三):單向鏈表。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

鏈表定義

鏈表是一種物理存儲單元上非連續(xù)、非順序的存儲結(jié)構(gòu),數(shù)據(jù)元素的邏輯是通過鏈表種的指針鏈接次序?qū)崿F(xiàn)的。鏈表由一系列節(jié)點組成,每個節(jié)點包括兩部分:一個是存儲數(shù)據(jù)元素的數(shù)據(jù)域,一個是存儲下一個節(jié)點地址的指針域。單向鏈表從頭節(jié)點(也可以沒有頭節(jié)點)開始,指針指向下一個節(jié)點的位置,只能由上一個節(jié)點指向后面節(jié)點,后面節(jié)點不能指向前面節(jié)點。單向鏈表示意圖
數(shù)據(jù)結(jié)構(gòu)與算法(三):單向鏈表

節(jié)點結(jié)構(gòu)

節(jié)點包含了數(shù)據(jù)域和指針域。數(shù)據(jù)域存放該節(jié)點存放的數(shù)據(jù)信息,指針域存放下一個節(jié)點的存儲地址。no、nickName、name為該節(jié)點的數(shù)據(jù)內(nèi)容,nextNode為下一個節(jié)點。

public class Node {
    private Integer no;
    private String name;
    private String nickName;
    private Node nextNode;
    public Node(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }
    @Override
    public String toString() {
        return "Node{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }
}

鏈表操作

初始化單向鏈表

初始化鏈表的頭節(jié)點,頭節(jié)點數(shù)據(jù)域為空,指針域為下一個節(jié)點的位置。

private Node head = new Node(0, "", "");

遍歷鏈表

因為單向鏈表的頭節(jié)點不能移動,所以借助一個臨時節(jié)點變量進(jìn)行遍歷。

public void showLinkList() {
    if (head.getNextNode() == null) {
        System.out.println("鏈表為空");
        return;
    }
    Node temp = head.getNextNode();
    while (true) {
        if (temp == null) {
            break;
        }
        System.out.println(temp);
        temp = temp.getNextNode();
    }
}

插入元素

該方法只是將新的節(jié)點放到節(jié)點的末尾去,并不考慮順序等因素。

public void addNode(Node node) {
   // 因為head是不能動的,所以需要借助一個臨時變量
   Node temp = head;
   while (true) {
       if (temp.getNextNode() == null) {
           break;
       }
       temp = temp.getNextNode();
   }
   temp.setNextNode(node);
}

該方法將新的節(jié)點放到節(jié)點中去,考慮節(jié)點的順序(以節(jié)點的 no 屬性為順序)。

public void addSortNode(Node node) {
    Node temp = head;
    boolean isExist = false;
    while (true) {
        if (temp.getNextNode() == null) {
            break;
        }
        // 對應(yīng)的序號已經(jīng)存在
        if (temp.getNo().equals(node.getNo())) {
            isExist = true;
            break;
        }
        if (temp.getNextNode().getNo() > node.getNo()) {
            break;
        }
        temp = temp.getNextNode();
    }
    if (isExist) {
        System.out.println("插入的序號 " + node.getNo() + " 已存在");
    } else {
        node.setNextNode(temp.getNextNode());
        temp.setNextNode(node);
    }
}

更新節(jié)點

更新某一個節(jié)點的數(shù)據(jù)域內(nèi)容

public void updateNode(Node node) {
    if (head.getName().equals("")) {
        System.out.println("鏈表為空");
    }
    Node temp = head.getNextNode();
    while (true) {
        if (temp == null) {
            break;
        }
        if (temp.getNo() == node.getNo()) {
            break;
        }
        temp = temp.getNextNode();
    }
    if (temp == null || temp.getNo() != node.getNo()) {
        System.out.println("沒有找到對應(yīng)的節(jié)點");
    } else {
        temp.setName(node.getName());
        temp.setNickName(node.getNickName());
    }
}

刪除節(jié)點

找到要刪除節(jié)點的上一個節(jié)點,將該節(jié)點的指針域設(shè)置成要刪除節(jié)點的下一個節(jié)點,這樣要刪除的節(jié)點就沒有指針指向了,就會被GC回收,達(dá)到刪除節(jié)點的目的。

public void deleteNode(Integer no) {
    if (head.getNextNode() == null) {
        System.out.println("鏈表為空");
    }
    Node temp = head;
    while (true) {
        if (temp.getNextNode() == null) {
            break;
        }
        if (temp.getNextNode().getNo() == no) {
            break;
        }
        temp = temp.getNextNode();
    }
    if (temp.getNextNode() == null) {
        System.out.println("未找到節(jié)點");
        return;
    }
    temp.setNextNode(temp.getNextNode().getNextNode());
}

有效節(jié)點的個數(shù)

public Integer getListNodeConunt() {
    if (head.getNextNode() == null) {
        return 0;
    }
    Node temp = head.getNextNode();
    Integer count = 0;
    while (true) {
        if (temp == null) {
            break;
        }
        count++;
        temp = temp.getNextNode();
    }
    return count;
}

倒數(shù){}個節(jié)點

因為單向鏈表的后一個節(jié)點是無法獲取到前一個節(jié)點的位置的,所以我們先計算出該鏈表的有效節(jié)點個數(shù),再用有效節(jié)點個數(shù) - 倒數(shù)的節(jié)點個數(shù)就是正數(shù)的節(jié)點個數(shù),這樣可以達(dá)到同樣的效果。

public Node getLastNode(SingleLinkList list, Integer index) {
    Integer count = list.getListNodeConunt();
    if (Optional.of(list).isEmpty()) {
        return null;
    }
    // 第幾個元素
    Integer indexPosition = 0;
    Node temp = head.getNextNode();
    while (true) {
        if (temp == null) {
            break;
        }
        // 因為鏈表是單向的,只能從前往后找,倒數(shù)第幾個=總數(shù)-倒數(shù)的數(shù)
        if (indexPosition == (count - index)) {
            return temp;
        }
        indexPosition++;
        temp = temp.getNextNode();
    }
    return null;
}

鏈表反轉(zhuǎn)

遍歷舊鏈表,第一個節(jié)點放入新鏈表的第一個節(jié)點,第二個節(jié)點的下一個節(jié)點設(shè)置成新鏈表的第一個節(jié)點,以此類推,舊鏈表的第一個就成了新鏈表的最后一個節(jié)點,第二個節(jié)點就成了新鏈表的倒數(shù)第二個節(jié)點...

public void getReverseList(Node head) {
    // 如果當(dāng)前鏈表為空,或者只有一個節(jié)點,無需反轉(zhuǎn),直接返回
    if (head.getNextNode() == null || head.getNextNode().getNextNode() == null) {
        return;
    }
    // 定義一個輔助變量,幫助遍歷原來的鏈表
    Node cur = head.getNextNode();
    // 指向當(dāng)前節(jié)點cur的下一個節(jié)點
    Node next = null;
    Node reverseHead = new Node(0, "", "");
    // 遍歷原來的鏈表,每遍歷一個節(jié)點,就將其取出,并放在新的鏈表reverseHead的最前端
    while (cur != null) {
        // 先暫時保存當(dāng)前節(jié)點的下一個節(jié)點,因為后面需要使用
        next = cur.getNextNode();
        // 將cur的下一個節(jié)點指向新的鏈表的最前端
        cur.setNextNode(reverseHead.getNextNode());
        reverseHead.setNextNode(cur);
        // 讓cur后移
        cur = next;
    }
    // 將head.next 指向reverseHead.next,實現(xiàn)單鏈表的反轉(zhuǎn)
    head.setNextNode(reverseHead.getNextNode());
}

逆序打印

利用棧結(jié)構(gòu)先進(jìn)后出的特點,將遍歷的鏈表節(jié)點依次入棧,再打印棧中的節(jié)點,這樣可以在不改變原來鏈表數(shù)據(jù)的情況下進(jìn)行逆序打印輸出。文章來源地址http://www.zghlxwxcb.cn/news/detail-618693.html

public void reversePrint(Node head) {
    if (head.getNextNode() == null) {
        return;
    }
    // 創(chuàng)建一個棧,將各個節(jié)點壓入棧
    Stack<Node> stack = new Stack<>();
    Node cur = head.getNextNode();
    while (cur != null) {
        stack.push(cur);
        cur = cur.getNextNode();
    }
    while (stack.size() > 0) {
        System.out.println(stack.pop());
    }
}

到了這里,關(guān)于數(shù)據(jù)結(jié)構(gòu)與算法(三):單向鏈表的文章就介紹完了。如果您還想了解更多內(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ìn)行投訴反饋,一經(jīng)查實,立即刪除!

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

相關(guān)文章

  • 【數(shù)據(jù)結(jié)構(gòu)】動圖詳解單向鏈表

    【數(shù)據(jù)結(jié)構(gòu)】動圖詳解單向鏈表

    目錄 1.什么是鏈表 ? ? ? ? 1.問題引入 ? ? ? ? 2. 鏈表的概念及結(jié)構(gòu) ? ? ? ? 3. 問題解決 2.單向鏈表接口的實現(xiàn) ????????1.接口1,2---頭插,尾插 ????????2. 接口3,4---頭刪,尾刪 ????????3. 接口5---查找 ?????????4. 接口6,7---插入,刪除 ????????5.?接口

    2024年01月18日
    瀏覽(27)
  • 【數(shù)據(jù)結(jié)構(gòu)篇】手寫雙向鏈表、單向鏈表(超詳細(xì))

    【數(shù)據(jù)結(jié)構(gòu)篇】手寫雙向鏈表、單向鏈表(超詳細(xì))

    什么是鏈表 ? 鏈表(Linked List)是用鏈?zhǔn)酱鎯Y(jié)構(gòu)實現(xiàn)的線性表。鏈表示意圖: 鏈表的組成 : 數(shù)據(jù)域 + 引用域 (數(shù)據(jù)域和引用域合稱結(jié)點或元素) 數(shù)據(jù)域存放數(shù)據(jù)元素自身的數(shù)據(jù) 引用域存放相鄰結(jié)點的地址 鏈表的特點 : 鏈表中元素的聯(lián)系依靠引用域 具有線性結(jié)構(gòu)的特

    2024年02月11日
    瀏覽(29)
  • 數(shù)據(jù)結(jié)構(gòu)——單向鏈表(C語言版)

    在數(shù)據(jù)結(jié)構(gòu)和算法中,鏈表是一種常見的數(shù)據(jù)結(jié)構(gòu),它由一系列節(jié)點組成,每個節(jié)點包含數(shù)據(jù)和指向下一個節(jié)點的指針。在C語言中,我們可以使用指針來實現(xiàn)單向鏈表。下面將詳細(xì)介紹如何用C語言實現(xiàn)單向鏈表。 目錄 1. 定義節(jié)點結(jié)構(gòu)體 2. 初始化鏈表 3. 插入節(jié)點 4. 刪除節(jié)點

    2024年03月24日
    瀏覽(33)
  • 【數(shù)據(jù)結(jié)構(gòu)】單向鏈表實現(xiàn) 超詳細(xì)

    【數(shù)據(jù)結(jié)構(gòu)】單向鏈表實現(xiàn) 超詳細(xì)

    目錄 一. 單鏈表的實現(xiàn) 1.準(zhǔn)備工作及其注意事項 1.1 先創(chuàng)建三個文件 1.2 注意事項:幫助高效記憶和理解 2.鏈表的基本功能接口 2.0 創(chuàng)建一個 鏈表 2.1 鏈表的 打印 ?3.鏈表的創(chuàng)建新節(jié)點接口 4.鏈表的節(jié)點 插入 功能接口 4.1 尾插接口 4.2 頭插接口 ? ??4.3 指定位置 pos 之前? 插入

    2024年02月19日
    瀏覽(23)
  • 數(shù)據(jù)結(jié)構(gòu):線性表之-單向鏈表(無頭)

    數(shù)據(jù)結(jié)構(gòu):線性表之-單向鏈表(無頭)

    目錄 什么是單向鏈表 順序表和鏈表的區(qū)別和聯(lián)系 順序表: 鏈表: 鏈表表示(單項)和實現(xiàn) 1.1 鏈表的概念及結(jié)構(gòu) 1.2單鏈表(無頭)的實現(xiàn) 所用文件 將有以下功能: 鏈表定義 創(chuàng)建新鏈表元素 尾插 頭插 尾刪 頭刪 查找-給一個節(jié)點的指針 改 pos位置之前插入 刪除pos位置的值 成品

    2024年02月09日
    瀏覽(92)
  • 數(shù)據(jù)結(jié)構(gòu)《鏈表》無頭單向非循環(huán)-動圖詳解

    數(shù)據(jù)結(jié)構(gòu)《鏈表》無頭單向非循環(huán)-動圖詳解

    前面學(xué)習(xí)了順序表發(fā)現(xiàn),順序表雖然好,但也有很多不足的地方,比方說,順序表是一塊連續(xù)的物理空間,如果頭插或者頭刪,那么整個數(shù)組的數(shù)據(jù)都要移動。但是鏈表不一樣,鏈表是通過指針訪問或者調(diào)整,鏈表是物理空間是不連續(xù)的,通過當(dāng)前的next指針找到下一個。 插

    2024年02月06日
    瀏覽(19)
  • 數(shù)據(jù)結(jié)構(gòu)day06(單向循環(huán)鏈表、雙向鏈表)

    數(shù)據(jù)結(jié)構(gòu)day06(單向循環(huán)鏈表、雙向鏈表)

    雙向鏈表的練習(xí)代碼 head.h fun.c main.c 今日思維導(dǎo)圖哈 ???????

    2024年02月10日
    瀏覽(15)
  • 第14章_集合與數(shù)據(jù)結(jié)構(gòu)拓展練習(xí)(前序、中序、后序遍歷,線性結(jié)構(gòu),單向鏈表構(gòu)建,單向鏈表及其反轉(zhuǎn),字符串壓縮)

    第14章_集合與數(shù)據(jù)結(jié)構(gòu)拓展練習(xí)(前序、中序、后序遍歷,線性結(jié)構(gòu),單向鏈表構(gòu)建,單向鏈表及其反轉(zhuǎn),字符串壓縮)

    1、前序、中序、后序遍歷 分析: 完全二叉樹: 葉結(jié)點只能出現(xiàn)在最底層的兩層,且最底層葉結(jié)點均處于次底層葉結(jié)點的左側(cè) 2、線性結(jié)構(gòu) 3、其它 4、單向鏈表構(gòu)建 (1)定義一個單向鏈表SingleLinked類 包含私有的靜態(tài)內(nèi)部類Node 包含Object類型的data屬性和Node類型的next屬性 包含

    2024年01月23日
    瀏覽(21)
  • 【數(shù)據(jù)結(jié)構(gòu)】之十分好用的“鏈表”趕緊學(xué)起來!(第一部分單向鏈表)

    【數(shù)據(jù)結(jié)構(gòu)】之十分好用的“鏈表”趕緊學(xué)起來!(第一部分單向鏈表)

    ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???? ?? ?? ?? 個人主頁 :阿然成長日記 ??點擊可跳轉(zhuǎn) ?? 個人專欄: ??數(shù)據(jù)結(jié)構(gòu)與算法??C語言進(jìn)階 ?? 不能則學(xué),不知則問,恥于問人,決無長進(jìn) ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 前言 ??小伙伴們,

    2024年02月14日
    瀏覽(28)
  • 【數(shù)據(jù)結(jié)構(gòu)C/C++】單向鏈表的增刪改查

    單向鏈表是比較常用的數(shù)據(jù)結(jié)構(gòu),最近再面試手撕算法的時候偶爾有遇到,所以就花了一點時間簡單的寫了一下C/C++版本的單向鏈表的代碼。 這里我推薦使用C++版本,因為C++版本我特地優(yōu)化了一下,提供了用戶輸入的功能,當(dāng)然兩個語言差異不大,注釋可以直接看C版本的,比

    2024年02月07日
    瀏覽(18)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包