双向链表、单项环形链表、约瑟夫问题

29 阅读2分钟

4.4双向链表

1664798560851.png

双向链表的增删改查:

1664798616681.png

代码实现:

package LinkedList;
​
public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        HeroNode2 h1 = new HeroNode2(1, "h1", "nh1");
        HeroNode2 h2 = new HeroNode2(2, "h2", "nh2");
        HeroNode2 h4 = new HeroNode2(4, "h4", "nh4");
        HeroNode2 h3 = new HeroNode2(3, "h3", "nh3");
        HeroNode2 h5 = new HeroNode2(3, "h5", "nh5");
        HeroNode2 h6 = new HeroNode2(8, "h8", "nh8");
        HeroNode2 h7 = new HeroNode2(6, "h6", "nh6");
        DoubleLinkedList hList = new DoubleLinkedList();
        hList.addByOrder(h1);
        hList.addByOrder(h2);
        hList.addByOrder(h4);
        hList.addByOrder(h3);
        hList.addByOrder(h6);
        hList.addByOrder(h6);
        hList.list();
    }
}
class HeroNode2 {
    public int no;
    public String name;
    public String nickname;
    public HeroNode2 next;
    public HeroNode2 pre;
​
    public HeroNode2(int hno, String hName, String hNickname) {
        this.no = hno;
        this.name = hName;
        this.nickname = hNickname;
    }
​
    @Override
    public String toString() {
        return "HeroNode2{" +
                "no=" + no +
                ", name='" + name + ''' +
                ", nickname='" + nickname + ''' +
                '}';
    }
}
​
class DoubleLinkedList {
    public HeroNode2 headNode = new HeroNode2(0, "", "");
    // 返回头节点
    public HeroNode2 getHead() {
        return headNode;
    };
    // 遍历双向链表
    public void list() {
        if (headNode.next == null) {
            System.out.println("链表为空");
            return;
        }
        HeroNode2 temp = headNode.next;
        while (true) {
            if (temp == null) {
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }
    // 添加
    public void add(HeroNode2 heroNode) {
        HeroNode2 temp = headNode;
        while (true) {
            if (temp.next == null) {
                break;
            }
            temp = temp.next;
        }
        temp.next = heroNode;
        heroNode.pre = temp;
    }
    // 按顺序添加一个节点
    public void addByOrder(HeroNode2 heroNode) {
        // 定义一个辅助指针
        HeroNode2 helper = headNode;
        boolean flag = false;
        while (true) {
            if (helper.next == null) {
                break;
            }
            if (helper.next.no > heroNode.no) {
                break;
            }
            if (helper.next.no == heroNode.no) {
                flag = true;
                break;
            }
            helper = helper.next;
        }
        if (flag) {
            System.out.printf("添加的元素%d已经存在", heroNode.no);
        } else {
            if (helper.next != null) {
                heroNode.next = helper.next;
                helper.next.pre = heroNode;
                heroNode.pre = helper;
                helper.next = heroNode;
            }else{
                helper.next = heroNode;
                heroNode.pre = helper;
            }
        }
    }
    // 删除一个节点
    public void del(int no) {
        if(headNode.next == null) {
            System.out.println("链表为空");
            return;
        }
        // 定义一个辅助指针
        HeroNode2 helper = headNode.next;
        boolean flag = false;
        while (true) {
            if (helper == null) {
                break;
            }
            if (helper.no == no) {
                flag = true;
                break;
            }
            helper = helper.next;
        }
        // 注意这里需要考虑,如果是删除最后一个节点,要防止出现空指针的情况
        if (flag) {
            helper.pre.next = helper.next;
            if (helper.next != null) {
                helper.next.pre = helper.pre;
            }
        } else {
            System.out.printf("要删除的节点%d不存在 \n", no);
        }
    }
    // 修改一个节点
    public void update(HeroNode2 newHero) {
        if(headNode.next == null){
            System.out.println("链表为空");
            return;
        }
        HeroNode2 temp = headNode.next;
        boolean flag = false;
        while (true) {
            if (temp == null) {
                break;
            }
            if (temp.no == newHero.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            temp.name = newHero.name;
            temp.nickname = newHero.nickname;
        } else {
            System.out.printf("找不到编号为%d的英雄,无法更新", newHero.no);
        }
    }
}

4.5单项环形链表和约瑟夫问题

约瑟夫问题解决思路

用一个不带头结点的循环链表来解决约瑟夫问题:线构成一个有n个节点的单循环链表,然后从K节点起从1开始计数,记到m时,对应节点从链表中删除,然后再从被删除节点的下一个节点又从1开始计数,直到最后一个节点从链表中删除算法结束。

1664799109127.png

代码实现:

package LinkedList;
​
public class JosePhuDemo {
    public static void main(String[] args) {
        CircleSingleLinkedList circleList = new CircleSingleLinkedList();
        circleList.addBoy(100);
        circleList.showBoy();
        circleList.countBoy(1, 7, 100);
    }
​
}
class CircleSingleLinkedList {
    private Boy first = null;
    public void addBoy (int numbs) {
        Boy helper = null;
        if (numbs < 1) {
            System.out.println("你输入的数没有意义,请重新输入");
            return;
        }
        for (int i = 1; i <= numbs; i++) {
            Boy newBoy = new Boy(i);
            if (i == 1) {
                first = newBoy;
                first.setNext(first);
                helper = first;
            } else {
                helper.setNext(newBoy);
                newBoy.setNext(first);
                helper = newBoy;
            }
        }
    }
    public void showBoy () {
        if (first == null) {
            System.out.println("没有任何小孩");
            return;
        }
        Boy helper = first;
        while (true) {
            System.out.println(helper.getNo());
            if(helper.getNext() == first) {
                break;
            }
            helper = helper.getNext();
        }
    }
    public void countBoy (int startNum, int countNum, int num) {
        if (startNum < 1 || countNum > num || startNum > num || first == null) {
            System.out.println("输入条件不符合条件");
            return;
        }
        Boy helper = first;
        while (true) {
            if (helper.getNext() == first) {
                break;
            }
            helper = helper.getNext();
        }
        for(int i=1; i < startNum; i++) {
            first = first.getNext();
            helper = helper.getNext();
        }
        while (true) {
            if (helper == first) {
                break;
            }
            for (int j=1; j < countNum; j++) {
                first = first.getNext();
                helper = helper.getNext();
            }
            System.out.printf("小孩%d出圈", first.getNo());
            first = first.getNext();
            helper.setNext(first);
        }
        System.out.printf("此时留在圈内的小孩是%d", first.getNo());
    }
}
​
​
class Boy {
    private int no;
    private Boy next;
​
    public Boy(int no) {
        this.no = no;
    }
​
    public int getNo() {
        return no;
    }
​
    public void setNo(int no) {
        this.no = no;
    }
​
    public Boy getNext() {
        return next;
    }
​
    public void setNext(Boy next) {
        this.next = next;
    }
}

\