亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java數(shù)據(jù)結構之雙向鏈表的實現(xiàn)

 更新時間:2023年03月20日 11:55:05   作者:興趣使然黃小黃  
相較單鏈表,雙向鏈表除了data與next域,還多了一個pre域用于表示每個節(jié)點的前一個元素。這樣做給雙向鏈表帶來了很多優(yōu)勢。本文主要介紹了雙向鏈表的實現(xiàn),需要的可以參考一下

1 雙向鏈表

1.1 雙向鏈表介紹

相較單鏈表,雙向鏈表除了data與next域,還多了一個pre域用于表示每個節(jié)點的前一個元素。這樣做給雙向鏈表帶來了很多優(yōu)勢:

單向鏈表查找的方向只能是一個方向,而雙向鏈表可以向前或者向后查找;

單鏈表如果想要實現(xiàn)刪除操作,需要找到待刪除節(jié)點的前一個節(jié)點。而雙向鏈表可以實現(xiàn)自我刪除。

雙向鏈表結構示意圖如下:

1.2 雙向鏈表實現(xiàn)思路

與單鏈表實現(xiàn)類似,交集部分不再贅述,詳情可參考文章:Java數(shù)據(jù)結構:單鏈表的實現(xiàn)與面試題匯總

遍歷:

與單鏈表遍歷方式一樣,同時,雙向鏈表可以支持向前和向后兩種查找方式

添加:

添加到末尾

  • 先找到雙向鏈表最后一個節(jié)點
  • cur.next = newNode;
  • newNode.pre = cur;

按照no順序添加

  • 先判斷該鏈表是否為空,如果為空則直接添加
  • 如果不為空則繼續(xù)處理
  • 根據(jù)no遍歷鏈表,找到合適的位置
  • newNode.next = cur.next;
  • cur.next = newNode;
  • newNode.pre = cur;

修改操作與單鏈表實現(xiàn)步驟一致

刪除操作:

  • 雙向鏈表可以實現(xiàn)自我刪除
  • 直接找到待刪除的節(jié)點
  • cur.pre.next = cur.next;
  • cur.next.pre = cur.pre;
  • 需要特別注意是否為最后一個元素,如果為最后一個元素,cur.next為null,此時使用cur.next.pre會出現(xiàn)空指針異常,所以,如果為最后一個元素,則該步驟可以省略,cur.next為null即可。

以刪除紅色的2號節(jié)點為例:

2 雙向鏈表實現(xiàn)完整代碼

2.1 節(jié)點類 Student.java

/**
 * @author 興趣使然黃小黃
 * @version 1.0
 * 學生類節(jié)點
 */
public class StudentNode {
    public String no; //學號
    public String name; //姓名
    public int age; //年齡
    public StudentNode pre; //指向前一個節(jié)點
    public StudentNode next; //指向下一個節(jié)點

    //構造器
    public StudentNode(String no, String name, int age ){
        this.no = no;
        this.name = name;
        this.age = age;
    }

    //為了顯示方便
    @Override
    public String toString() {
        return "StudentNode{" +
                "no='" + no + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2.2 雙向鏈表實現(xiàn)類 StudentDoubleLinkedList.java

/**
 * @author 興趣使然黃小黃
 * @version 1.0
 * 學生雙向鏈表的具體實現(xiàn)
 */
public class StudentDoubleLinkedList {
    //定義頭節(jié)點
    private StudentNode head = new StudentNode("", "", 0);

    //獲取頭節(jié)點
    public StudentNode getHead(){
        return head;
    }

    //遍歷雙向鏈表的方法
    public void showList(){
        //判斷鏈表是否為空
        if (head.next == null){
            System.out.println("當前鏈表為空");
            return;
        }
        //遍歷 使用輔助指針
        StudentNode temp = head;
        while (temp != null){
            //更新指針
            temp = temp.next;
            if (temp.next == null){
                System.out.print(temp);
                break;
            }
            System.out.print(temp + "--->");
        }
    }

    //添加節(jié)點的方法
    //添加到尾部
    public void add(StudentNode newNode){
        //先找到最后一個節(jié)點
        StudentNode cur = head;
        while (true){
            //到達最后退出循環(huán)
            if (cur.next == null){
                break;
            }
            //更新指針
            cur = cur.next;
        }
        //添加操作
        newNode.next = cur.next; //也可以省略,因為恒為null
        cur.next = newNode;
        newNode.pre = cur;
    }

    //添加節(jié)點的方法
    //根據(jù)學號順序添加
    public void addByOrder(StudentNode newNode){
        //如果當前鏈表為空,則直接添加
        if (head.next == null){
            head.next = newNode;
            newNode.pre = head;
            return;
        }
        //按照學號找到對應位置
        StudentNode cur = head;
        boolean flag = false; //標識待添加的no是否存在
        while (true){
            if (cur.next == null){
                //已經(jīng)到達鏈表的尾部
                break;
            } else if (Integer.parseInt(cur.next.no) == Integer.parseInt(newNode.no)){
                //已經(jīng)存在
                flag = true;
                break;
            }else if (Integer.parseInt(cur.next.no) > Integer.parseInt(newNode.no)){
                //位置找到
                break;
            }
            cur = cur.next;
        }
        if (flag){
            System.out.println("當前no已經(jīng)存在,無法添加!");
        }else {
            //添加操作
            newNode.next = cur.next;
            cur.next = newNode;
            newNode.pre = cur;
        }
    }

    //根據(jù)no學號修改學生信息
    public void update(StudentNode studentNode){
        if (head.next == null){
            System.out.println("當前鏈表為空, 無法修改");
            return;
        }
        StudentNode temp = head.next;
        boolean flag = false; //表示是否找到節(jié)點
        while (true){
            if (temp == null){
                break;
            }
            if (temp.no == studentNode.no){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag){
            temp.name = studentNode.name;
            temp.age = studentNode.age;
            System.out.println("更新成功!");
        }else {
            System.out.println("沒有找到");
        }
    }

    //從雙向鏈表中刪除節(jié)點
    public void delete(String no){
        //直接找到對應no的節(jié)點直接刪除
        StudentNode cur = head.next;
        boolean flag = false; //標記是否找到
        while (true){
            if (cur == null){
                break;
            }
            if (cur.no.equals(no)){
                flag = true; //找到了
                break;
            }
            cur = cur.next;
        }
        if (flag){
            //刪除操作
            //注意考慮最后一個節(jié)點后一個為空的情況
            if (cur.next != null) {
                cur.next.pre = cur.pre;
            }
            cur.pre.next = cur.next;
            System.out.println("刪除成功!");
        }else {
            System.out.println( no + "節(jié)點不存在,無法刪除!");
        }
    }
}

2.3 測試類 StudentDoubleLinkedListDemo.java

/**
 * @author 興趣使然黃小黃
 * @version 1.0
 * 雙向鏈表測試類
 */
public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        StudentDoubleLinkedList doubleLinkedList = new StudentDoubleLinkedList();
        doubleLinkedList.addByOrder(new StudentNode("1", "黃小黃", 20));
        doubleLinkedList.addByOrder(new StudentNode("3", "懶羊羊", 20));
        doubleLinkedList.addByOrder(new StudentNode("2", "沸羊羊", 25));
        doubleLinkedList.addByOrder(new StudentNode("4", "美羊羊", 15));
        System.out.println("遍歷:");
        doubleLinkedList.showList();

        //測試更新方法
        System.out.println("\n更新編號為4的信息后:");
        doubleLinkedList.update(new StudentNode("4", "禰豆子", 14));
        doubleLinkedList.showList();

        //測試刪除方法
        System.out.println("\n刪除第一個和最后一個:");
        doubleLinkedList.delete("1");
        doubleLinkedList.delete("4");
        doubleLinkedList.showList();
    }
}

2.4 結果

遍歷:
StudentNode{no='1', name='黃小黃', age=20}--->StudentNode{no='2', name='沸羊羊', age=25}--->StudentNode{no='3', name='懶羊羊', age=20}--->StudentNode{no='4', name='美羊羊', age=15}
更新編號為4的信息后:
更新成功!
StudentNode{no='1', name='黃小黃', age=20}--->StudentNode{no='2', name='沸羊羊', age=25}--->StudentNode{no='3', name='懶羊羊', age=20}--->StudentNode{no='4', name='禰豆子', age=14}
刪除第一個和最后一個:
刪除成功!
刪除成功!
StudentNode{no='2', name='沸羊羊', age=25}--->StudentNode{no='3', name='懶羊羊', age=20}
Process finished with exit code 0

3 雙向鏈表小結

單向鏈表查找的方向只能為一個方向,雙向鏈表解決了這個缺點,可以實現(xiàn)雙向查找;

單鏈表進行刪除操作必須找到待刪除元素的前一個元素,才能完成刪除操作。而雙向鏈表就簡單多了,只需要找到待刪除的節(jié)點,進行自我刪除;

本節(jié)介紹了雙向鏈表的遍歷、添加、按順序添加、更新、刪除方法的實現(xiàn),可以嘗試像單鏈表篇一樣,嘗試求有效節(jié)點數(shù)量,以及如何逆序輸出雙向鏈表加強練習!

以上就是Java數(shù)據(jù)結構之雙向鏈表的實現(xiàn)的詳細內(nèi)容,更多關于Java數(shù)據(jù)結構雙向鏈表的資料請關注腳本之家其它相關文章!

相關文章

  • Java中區(qū)別.toString() ,(String),valueOf()方法

    Java中區(qū)別.toString() ,(String),valueOf()方法

    這篇文章主要介紹了Java中區(qū)別.toString() ,(String),valueOf()方法,需要的朋友可以參考下
    2017-01-01
  • java中重寫父類方法加不加@Override詳解

    java中重寫父類方法加不加@Override詳解

    這篇文章主要介紹了java中重寫父類方法加不加@Override詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • MyBatis攔截器的實現(xiàn)原理

    MyBatis攔截器的實現(xiàn)原理

    這篇文章主要介紹了MyBatis攔截器的實現(xiàn)原理,Mybatis攔截器并不是每個對象里面的方法都可以被攔截的,其具體內(nèi)容感興趣的小伙伴課題參考一下下面文章內(nèi)容
    2022-08-08
  • 詳解MyBatis日志如何做到兼容所有常用的日志框架

    詳解MyBatis日志如何做到兼容所有常用的日志框架

    這篇文章主要介紹了詳解MyBatis日志如何做到兼容所有常用的日志框架,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • Java如何基于EasyExcel實現(xiàn)導入數(shù)據(jù)校驗并生成錯誤信息Excel

    Java如何基于EasyExcel實現(xiàn)導入數(shù)據(jù)校驗并生成錯誤信息Excel

    這篇文章主要介紹了Java如何基于EasyExcel實現(xiàn)導入數(shù)據(jù)校驗并生成錯誤信息Excel,為了優(yōu)化項目中的文件導入功能,考慮構建一個基于EasyExcel的通用Excel導入框架,主要解決導入數(shù)據(jù)的校驗問題,避免業(yè)務代碼中堆積大量校驗邏輯,需要的朋友可以參考下
    2024-09-09
  • spring boot配置druid連接池的完整步驟

    spring boot配置druid連接池的完整步驟

    這篇文章主要給大家介紹了關于spring boot配置druid連接池的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-01-01
  • 淺談Hibernate n+1問題

    淺談Hibernate n+1問題

    這篇文章主要介紹了淺談Hibernate n+1問題,怎么解決n+1問題,文中也作了簡要分析,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • SpringIOC?BeanDefinition的加載流程詳解

    SpringIOC?BeanDefinition的加載流程詳解

    這篇文章主要為大家介紹了SpringIOC?BeanDefinition的加載流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • SpringBoot Swagger2 接口規(guī)范示例詳解

    SpringBoot Swagger2 接口規(guī)范示例詳解

    Swagger(在谷歌、IBM、微軟等公司的支持下)做了一個公共的文檔風格來填補上述問題,在本文中,我們將會學習怎么使用Swagger的 Swagger2注解去生成REST API文檔,感興趣的朋友一起看看吧
    2023-12-12
  • 在Docker中部署Spring Boot項目過程詳解

    在Docker中部署Spring Boot項目過程詳解

    這篇文章主要介紹了在Docker中部署Spring Boot項目,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08

最新評論