1. 程式人生 > 其它 >【HuoLe的學習筆記】--雙向連結串列

【HuoLe的學習筆記】--雙向連結串列

技術標籤:HuoLe的學習筆記java資料結構連結串列

一、雙向連結串列:

  • 每個節點包含data域,pre域:指向前一個節點,next域:指向下一個節點
    在這裡插入圖片描述

  • 雙向連結串列的遍歷,新增、修改、刪除的操作思路

    • 遍歷方法和單鏈表一樣,只是可以向前,也可以向後查詢
    • 新增(預設新增到雙向連結串列的最後)
      • 方式一:預設加到最後
      • 先找到雙向連結串列的最後這個節點
      • temp.next = newNode;
      • newNode.pre = temp;
      • 方式二:根據排名(id)順序新增
      • 先找到雙向連結串列中可以新增節點的位置
      • studentNode.next = temp;//
        studentNode.pre = temp.pre;//用新節點取代當前temp的位置
      • temp.pre.next = studentNode;//temp.pre的下一個節點指向新節點
      • temp.pre = studentNode;//temp位置後移
      • java實現:

定義的add函式:

/**
     * 向連結串列中新增節點
     * @param studentNode
     */
    public void add(DualStudentNode studentNode){
        DualStudentNode temp = head;//輔助節點
        boolean flag = false;//標誌節點是否已經存在
        while (true
) { if (temp.id == studentNode.id){ flag = true;//如果連結串列中已存在該節點,置為true,跳出迴圈 break; } //尋找新加入節點的位置 else if (temp.id > studentNode.id && temp.pre.id < studentNode.id){//找到可以新增的位置,在temp.pre和temp之間 studentNode.
next = temp;// studentNode.pre = temp.pre;//用新節點取代當前temp的位置 temp.pre.next = studentNode;//temp.pre的下一個節點指向新節點 temp.pre = studentNode;//temp位置後移 break; } else if (temp.next == null){//遍歷到連結串列最後 temp.next = studentNode;//直接在連結串列最後新增新節點 studentNode.pre = temp;//新節點的上一個節點為temp break; } temp = temp.next; } if (flag){ System.out.printf("已存在節點%s",studentNode); } }

建立學生資訊:

        DualStudentNode student1 = new DualStudentNode(1,"尤雅","female");
        DualStudentNode student2 = new DualStudentNode(2,"李彤","female");
        DualStudentNode student3 = new DualStudentNode(3,"倪思帆","male");
        DualStudentNode student4 = new DualStudentNode(4,"邵浩","male");
        DualStudentNode student5 = new DualStudentNode(5,"韋思","male");
        DualStudentNode student6 = new DualStudentNode(6,"胡嫚嫚","female");
        DualStudentNode student7 = new DualStudentNode(7,"程俊遠","male");
        DualStudentNode student8 = new DualStudentNode(8,"姚汪鼎","male");
        DualStudentNode student9 = new DualStudentNode(9,"朱永琦","male");
        DualStudentNode student10 = new DualStudentNode(10,"周霜","female");
        DualStudentNode student11 = new DualStudentNode(11,"凌瑾","female");
        DualStudentNode student12 = new DualStudentNode(12,"應豐糠","male");
        DualStudentNode student13 = new DualStudentNode(13,"莊慧敏","female");
        DualStudentNode student14 = new DualStudentNode(14,"於符婷","female");
        DualStudentNode student15 = new DualStudentNode(15,"黃淦","male");
        DualStudentNode student16 = new DualStudentNode(16,"王祺","male");

亂序新增:

        dualLinkedList.add(student13);
        dualLinkedList.add(student1);
        dualLinkedList.add(student15);
        dualLinkedList.add(student7);
        dualLinkedList.add(student10);
        dualLinkedList.add(student9);
        dualLinkedList.add(student5);
        dualLinkedList.add(student14);
        dualLinkedList.add(student3);
        dualLinkedList.add(student12);
        dualLinkedList.add(student6);
        dualLinkedList.add(student8);
        dualLinkedList.add(student11);
        dualLinkedList.add(student4);
        dualLinkedList.add(student16);
        dualLinkedList.add(student2);

		dualLinkedList.show();

列印結果:

 TestDualLinkedList
StudentNode{id=1, name='尤雅', gender='female'}
StudentNode{id=2, name='李彤', gender='female'}
StudentNode{id=3, name='倪思帆', gender='male'}
StudentNode{id=4, name='邵浩', gender='male'}
StudentNode{id=5, name='韋思', gender='male'}
StudentNode{id=6, name='胡嫚嫚', gender='female'}
StudentNode{id=7, name='程俊遠', gender='male'}
StudentNode{id=8, name='姚汪鼎', gender='male'}
StudentNode{id=9, name='朱永琦', gender='male'}
StudentNode{id=10, name='周霜', gender='female'}
StudentNode{id=11, name='凌瑾', gender='female'}
StudentNode{id=12, name='應豐糠', gender='male'}
StudentNode{id=13, name='莊慧敏', gender='female'}
StudentNode{id=14, name='於符婷', gender='female'}
StudentNode{id=15, name='黃淦', gender='male'}
StudentNode{id=16, name='王祺', gender='male'}

Process finished with exit code 0

  • 修改和單向連結串列一樣:遍歷查詢–>修改
  • Java實現:
    定義的update函式:
/**
     * 更新節點資訊,根據節點id
     * @param studentNode
     */
    public void update(DualStudentNode studentNode){
        DualStudentNode temp = head.next;//輔助節點
        boolean flag = false;//標誌是否找到位置
        if (temp == null){
            System.out.println("連結串列為空");
        }
        //遍歷連結串列
        while (true){
            if (temp == null){
                break;
            }
            if (temp.id == studentNode.id){
                flag = true;//找到對應節點,置為true
                break;
            }
            temp = temp.next;
        }
        if (flag){
            //修改資訊
            temp.name = studentNode.name;
            temp.gender = studentNode.gender;
        }else {
            System.out.println("沒有對應節點可修改");
        }
    }

修改節點:

        DualStudentNode student1c = new DualStudentNode(1,"尤雅ya","maybefemale");
		dualLinkedList.update(student1c);
        dualLinkedList.show();

輸出結果:

TestDualLinkedList
原連結串列所有節點:
StudentNode{id=1, name='尤雅', gender='female'}
StudentNode{id=13, name='莊慧敏', gender='female'}
修改後的連結串列:
StudentNode{id=1, name='尤雅ya', gender='maybefemale'}
StudentNode{id=13, name='莊慧敏', gender='female'}

Process finished with exit code 0

  • 刪除
    • 因為是雙向連結串列,因此,可以實現自我刪除某個節點
    • 直接找到要刪除的節點,temp
    • temp.pre.next = temp.next
    • temp.next.pre = temp.pre
    • Java實現:
      定義的delete函式:
/**
     * 刪除節點,根據節點id
     * @param studentNode
     */
    public void delete(DualStudentNode studentNode){
        DualStudentNode temp = head.next;
        boolean flag = false;//標誌是否找到對應節點
        if (temp == null){
            System.out.println("連結串列為空");
        }
        //遍歷連結串列
        while (true){
            if (temp == null){
                break;
            }
            if (temp.id == studentNode.id){
                flag = true;//找到對應節點,置為true
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            //完成刪除
            temp.pre.next = temp.next;//temp的前一個節點的下一個節點置為temp的下一個節點
            temp.next.pre = temp.pre;//temp的下一個節點的上一個節點指向temp的上一個節點
        }else {
            System.out.println("沒有對應節點");
        }
    }

刪除對應節點:

		System.out.println("原連結串列所有節點:");
        dualLinkedList.show();
		System.out.println("刪除後連結串列所有節點:");
        dualLinkedList.delete(student1);
        dualLinkedList.show();

輸出結果:

原連結串列所有節點:
StudentNode{id=1, name='尤雅', gender='female'}
StudentNode{id=13, name='莊慧敏', gender='female'}
刪除後連結串列所有節點:
StudentNode{id=13, name='莊慧敏', gender='female'}

整體程式碼

public class TestDualLinkedList {
    public static void main(String[] args){
        DualStudentNode student1 = new DualStudentNode(1,"尤雅","female");
        DualStudentNode student1c = new DualStudentNode(1,"尤雅ya","maybefemale");
        DualStudentNode student2 = new DualStudentNode(2,"李彤","female");
        DualStudentNode student3 = new DualStudentNode(3,"倪思帆","male");
        DualStudentNode student4 = new DualStudentNode(4,"邵浩","male");
        DualStudentNode student5 = new DualStudentNode(5,"韋思","male");
        DualStudentNode student6 = new DualStudentNode(6,"胡嫚嫚","female");
        DualStudentNode student7 = new DualStudentNode(7,"程俊遠","male");
        DualStudentNode student8 = new DualStudentNode(8,"姚汪鼎","male");
        DualStudentNode student9 = new DualStudentNode(9,"朱永琦","male");
        DualStudentNode student10 = new DualStudentNode(10,"周霜","female");
        DualStudentNode student11 = new DualStudentNode(11,"凌瑾","female");
        DualStudentNode student12 = new DualStudentNode(12,"應豐糠","male");
        DualStudentNode student13 = new DualStudentNode(13,"莊慧敏","female");
        DualStudentNode student14 = new DualStudentNode(14,"於符婷","female");
        DualStudentNode student15 = new DualStudentNode(15,"黃淦","male");
        DualStudentNode student16 = new DualStudentNode(16,"王祺","male");

        DualLinkedList dualLinkedList = new DualLinkedList();
        dualLinkedList.add(student13);
        dualLinkedList.add(student1);
        dualLinkedList.add(student15);
        dualLinkedList.add(student7);
        dualLinkedList.add(student10);
        dualLinkedList.add(student9);
        dualLinkedList.add(student5);
        dualLinkedList.add(student14);
        dualLinkedList.add(student3);
        dualLinkedList.add(student12);
        dualLinkedList.add(student6);
        dualLinkedList.add(student8);
        dualLinkedList.add(student11);
        dualLinkedList.add(student4);
        dualLinkedList.add(student16);
        dualLinkedList.add(student2);
        System.out.println("原連結串列所有節點:");
        dualLinkedList.show();
        System.out.println("修改後的連結串列:");
        dualLinkedList.update(student1c);
        dualLinkedList.show();
        System.out.println("刪除後連結串列所有節點:");
        dualLinkedList.delete(student1);
        dualLinkedList.show();
    }
}

class DualLinkedList{
    DualStudentNode head = new DualStudentNode(0,"","");

    /**
     * 向連結串列中新增節點
     * @param studentNode
     */
    public void add(DualStudentNode studentNode){
        DualStudentNode temp = head;//輔助節點
        boolean flag = false;//標誌節點是否已經存在
        while (true) {
            if (temp.id == studentNode.id){
                flag = true;//如果連結串列中已存在該節點,置為true,跳出迴圈
                break;
            }
            //尋找新加入節點的位置
            else if (temp.id > studentNode.id && temp.pre.id < studentNode.id){//找到可以新增的位置,在temp.pre和temp之間
                studentNode.next = temp;//
                studentNode.pre = temp.pre;//用新節點取代當前temp的位置
                temp.pre.next = studentNode;//temp.pre的下一個節點指向新節點
                temp.pre = studentNode;//temp位置後移
                break;
            }
            else if (temp.next == null){//遍歷到連結串列最後
                temp.next = studentNode;//直接在連結串列最後新增新節點
                studentNode.pre = temp;//新節點的上一個節點為temp
                break;
            }
            temp = temp.next;
        }
        if (flag){
            System.out.printf("已存在節點%s",studentNode);
        }
    }

    /**
     * 更新節點資訊,根據節點id
     * @param studentNode
     */
    public void update(DualStudentNode studentNode){
        DualStudentNode temp = head.next;//輔助節點
        boolean flag = false;//標誌是否找到位置
        if (temp == null){
            System.out.println("連結串列為空");
        }
        //遍歷連結串列
        while (true){
            if (temp == null){
                break;
            }
            if (temp.id == studentNode.id){
                flag = true;//找到對應節點,置為true
                break;
            }
            temp = temp.next;
        }
        if (flag){
            //修改資訊
            temp.name = studentNode.name;
            temp.gender = studentNode.gender;
        }else {
            System.out.println("沒有對應節點可修改");
        }
    }

    /**
     * 刪除節點,根據節點id
     * @param studentNode
     */
    public void delete(DualStudentNode studentNode){
        DualStudentNode temp = head.next;
        boolean flag = false;//標誌是否找到對應節點
        if (temp == null){
            System.out.println("連結串列為空");
        }
        //遍歷連結串列
        while (true){
            if (temp == null){
                break;
            }
            if (temp.id == studentNode.id){
                flag = true;//找到對應節點,置為true
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            //完成刪除
            temp.pre.next = temp.next;//temp的前一個節點的下一個節點置為temp的下一個節點
            temp.next.pre = temp.pre;//temp的下一個節點的上一個節點指向temp的上一個節點
        }else {
            System.out.println("沒有對應節點");
        }
    }

    /**
     * 列印連結串列中所有節點
     */
    public void show(){
        //定義輔助變數
        DualStudentNode temp = head.next;
        if (temp == null){
            System.out.println("連結串列為空");
        }
        //遍歷連結串列
        while (true){
            if (temp == null){
                break;
            }
            System.out.println(temp);//列印節點
            temp = temp.next;
        }
    }
}

/**
 * 新建DualStudentNode節點類
 */
class DualStudentNode {
    int id;//學號
    String name;//姓名
    String gender;//性別
    DualStudentNode pre;//指向前一個節點
    DualStudentNode next;//指向下一個節點

    //建構函式
    public DualStudentNode (int id, String name, String gender) {
        this.id = id;
        this.name = name;
        this.gender = gender;
    }

    //重寫toString()方法
    @Override
    public String toString() {
        return "StudentNode{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}