數據結構與算法_1.稀疏數組和隊列_2

1.2 隊列


  • 單鏈表
    • 鏈表爲有序列表,在內存中的存儲如下:
      在這裏插入圖片描述
      1. 鏈表是以節點的方式來存儲,是鏈式存儲。
      2. 每個節點包含:data 域和 next 域(指向下一個節點)。
      3. 鏈表的各個節點不一定是連續存儲的。
      4. 鏈表分有頭節點的鏈表和沒有頭節點的鏈表,根據實際的需求來確定。
    • 代碼實現
/*
	1. 第一種方法:添加節點時,直接添加到鏈表尾部
*/
public class Demo01SingleLinkedList {
    public static void main(String[] args) {
        // 創建節點
        HeroNode hero1 = new HeroNode(1, "宋江", "及時雨");
        HeroNode hero2 = new HeroNode(2, "盧俊義", "玉麒麟");
        HeroNode hero3 = new HeroNode(3, "吳用", "智多星");
        HeroNode hero4 = new HeroNode(4, "林沖", "豹子頭");

        // 創建鏈表
        SingleLinkedList singleLinkedList = new SingleLinkedList();

        // 加入節點
        singleLinkedList.add(hero1);
        singleLinkedList.add(hero2);
        singleLinkedList.add(hero3);
        singleLinkedList.add(hero4);

        // 顯示鏈表
        singleLinkedList.list();
    }
}

// 定義SingleLinkedList,管理英雄
class SingleLinkedList {
    // 先初始化一個頭節點,頭節點不要動,不存放具體數據
    private HeroNode head = new HeroNode(0,"","");

    // 添加節點到單向鏈表
    /*
        思路:
            當不考慮編號順序時,
            1. 找到當前鏈表的最後節點
            2. 將最後這個節點的next指向新的節點
     */
    public void add(HeroNode heroNode) {
        // 需要一個輔助變量temp,因爲head節點不能動
        HeroNode temp = head;
        // 遍歷鏈表,找到最後一個節點
        while (true) {
            // 如果是最後,退出
            if (temp.next == null) {
                break;
            }
            // 如果不是最後,將temp後移一個
            temp = temp.next;
        }
        // 當退出while循環時,temp就指向了鏈表的最後
        // 將最後這個節點的next指向新的節點
        temp.next = heroNode;
    }

    // 顯示鏈表[遍歷]
    public void list() {
        // 判斷鏈表是否爲空
        if (head.next == null) {
            System.out.println("鏈表爲空");
            return;
        }
        // 需要一個輔助變量來遍歷,因爲頭節點不能動
        HeroNode temp = head.next;
        while (true) {
            // 判斷是否是鏈表最後
            if (temp == null) {
                break;
            }
            // 輸出節點的信息
            System.out.println(temp);
            // 將temp後移
            temp = temp.next;
        }
    }
}

// 定義HeroNode,每個HeroNode對象就是一個節點
class HeroNode {
    public int no;
    public String name;
    public String nickname;
    public HeroNode next;   // 指向下一個節點

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

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

/*
	2. 第二種方法:添加節點時,按照順序添加到鏈表指定位置
*/
public class Demo01SingleLinkedList {
    public static void main(String[] args) {
        // 創建節點
        HeroNode hero1 = new HeroNode(1, "宋江", "及時雨");
        HeroNode hero2 = new HeroNode(2, "盧俊義", "玉麒麟");
        HeroNode hero3 = new HeroNode(3, "吳用", "智多星");
        HeroNode hero4 = new HeroNode(4, "林沖", "豹子頭");

        // 創建鏈表
        SingleLinkedList singleLinkedList = new SingleLinkedList();

        // 加入節點(按照順序)
        singleLinkedList.addByOrder(hero1);
        singleLinkedList.addByOrder(hero4);
        singleLinkedList.addByOrder(hero2);
        singleLinkedList.addByOrder(hero3);

        // 顯示鏈表
        singleLinkedList.list();
    }
}

// 定義SingleLinkedList,管理英雄
class SingleLinkedList {
    // 先初始化一個頭節點,頭節點不要動,不存放具體數據
    private HeroNode head = new HeroNode(0,"","");

    // 添加節點到單向鏈表
    /*
        思路:
            當不考慮編號順序時,
            1. 找到當前鏈表的最後節點
            2. 將最後這個節點的next指向新的節點
     */
    public void add(HeroNode heroNode) {
        // 需要一個輔助變量temp,因爲head節點不能動
        HeroNode temp = head;
        // 遍歷鏈表,找到最後一個節點
        while (true) {
            // 如果是最後,退出
            if (temp.next == null) {
                break;
            }
            // 如果不是最後,將temp後移一個
            temp = temp.next;
        }
        // 當退出while循環時,temp就指向了鏈表的最後
        // 將最後這個節點的next指向新的節點
        temp.next = heroNode;
    }

    // 第二種方法添加節點,按照順序將節點添加到指定位置
    public void addByOrder(HeroNode heroNode) {
        // 頭節點不能動,需要一個輔助變量temp,幫助找到添加的位置
        // 因爲是單鏈表,因爲找的temp是位於添加位置的前一個節點
        HeroNode temp = head;
        boolean flag = false;   // flag標誌添加的編號是否存在,默認爲false
        while (true) {
            if (temp.next == null) {
                break;  // 已經在鏈表的最後
            }
            if (temp.next.no > heroNode.no) {
                // 位置找到,就在temp和temp.next之間插入
                break;
            } else if (temp.next.no == heroNode.no) {
                // 說明希望添加的heroNode的編號已經存在
                flag = true;
                break;
            }
            // temp後移
            temp = temp.next;
        }
        // 判斷flag值
        if (flag) {
            // 說明編號存在,不能添加
            System.out.printf("準別插入的英雄編號 %d 已經存在,不能加入\n", heroNode.no);
        } else {
            // 插入到鏈表中
            heroNode.next = temp.next;  // 將原先temp.next的值賦值給heroNode.next
            temp.next = heroNode;       // 再將heroNode賦值給temp.next
        }
    }

    // 顯示鏈表[遍歷]
    public void list() {
        // 判斷鏈表是否爲空
        if (head.next == null) {
            System.out.println("鏈表爲空");
            return;
        }
        // 需要一個輔助變量來遍歷,因爲頭節點不能動
        HeroNode temp = head.next;
        while (true) {
            // 判斷是否是鏈表最後
            if (temp == null) {
                break;
            }
            // 輸出節點的信息
            System.out.println(temp);
            // 將temp後移
            temp = temp.next;
        }
    }
}

// 定義HeroNode,每個HeroNode對象就是一個節點
class HeroNode {
    public int no;
    public String name;
    public String nickname;
    public HeroNode next;   // 指向下一個節點

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

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章