单向链表,双向链表及环形列表解决约瑟夫问题

下面的代码包括了单向链表的逆序打印
和将链表逆序,即将链表中的节点逆序连接

在这里插入图片描述
节点的插入(order by)
在这里插入图片描述
节点的删除
在这里插入图片描述
单链表的反转
在这里插入图片描述
逆序打印
利用栈的数据结构特点,遍历链表,将每个节点压入链表中,然后逐个弹出打印

package com.whb.linkedlisk;

import java.util.Stack;

public class SingleLinkedListDemo {
    
    

    public static void main(String[] args) {
    
    


        HeroNode h3 = new HeroNode(3, "周瑜", "火");
        HeroNode h1 = new HeroNode(1, "小乔", "扇子");
        HeroNode h2 = new HeroNode(2, "鲁班", "枪");
        HeroNode h4 = new HeroNode(4, "曹操", "剑");

        SingleLinkedList link = new SingleLinkedList();
        link.add(h1);
        link.add(h4);
        link.add(h3);
        link.add(h2);

//        link.addByOrder(h4);
//        link.addByOrder(h1);
//        link.addByOrder(h3);
//        link.addByOrder(h2);

        link.list();
        System.out.println();

        // 测试逆序打印
        reversePrint(link.getHead());


//        System.out.println();
//
//        HeroNode newH = new HeroNode(2, "小鲁", "手");
//        link.update(newH);
//
//        link.list();

//        System.out.println();
//
//        link.del(1);
//        link.del(4);
//        link.del(5);
//        link.del(2);
//        link.list();

//        System.out.println();
//
//        // 测试单链表的反转
//        reverseList(link.getHead());
//        link.list();

    }

    public static void reversePrint(HeroNode head){
    
    
        Stack<HeroNode> stack = new Stack<>();

        HeroNode temp = head.next;

        while (true){
    
    

            if (temp==null){
    
    
                break;
            }

            stack.add(temp);

            temp = temp.next;
        }

        while (stack.size()>0){
    
    
            System.out.println(stack.pop());
        }

    }

    /**
     * 单链表反转
     * @param head
     */
    public static void reverseList(HeroNode head){
    
    

        if(head.next==null || head.next.next==null){
    
    
            return;
        }

        HeroNode cur = head.next;
        HeroNode next = cur;
        HeroNode reverseHead = new HeroNode(0, "", "");

        while (true){
    
    

            if(next==null){
    
    
                break;
            }

            next = cur.next;
            cur.next = reverseHead.next;
            reverseHead.next = cur;

            cur = next;

        }

        head.next = reverseHead.next;
    }

}


class SingleLinkedList{
    
    
    private HeroNode head = new HeroNode(0, "", "");


    public HeroNode getHead(){
    
    
        return head;
    }

    /**
     * 添加到末尾
     * @param heroNode
     */
    public void add(HeroNode heroNode){
    
    

        HeroNode temp = head;
        while (true){
    
    
            if(temp.next==null){
    
    
                break;
            }
            temp = temp.next;
        }
        temp.next = heroNode;
    }

    /**
     * 通过Hero的编号顺序插入到链表中
     * @param heroNode
     */
    public void addByOrder(HeroNode heroNode){
    
    

        HeroNode temp = head;

        while (true){
    
    

            if(temp.next==null){
    
    
                break;
            }else if(temp.next.no > heroNode.no){
    
      // 找到要插入的位置
                break;
            }else if (temp.next.no == heroNode.no){
    
    
                System.out.println("当前插入英雄的标号为:"+heroNode.no+"  编号已经存在, 插入失败");
                return;
            }

            temp = temp.next;
        }
        heroNode.next = temp.next;
        temp.next = heroNode;
    }


    /**
     * 修改
     * @param newHeroNode
     */
    public void update(HeroNode newHeroNode){
    
    

        HeroNode temp = head.next;
        while (true){
    
    
            if(temp == null){
    
    
                System.out.println("未找到要修改的节点");
                return;
            }

            if(temp.no == newHeroNode.no){
    
    
                break;
            }
            temp = temp.next;
        }

        temp.name = newHeroNode.name;
        temp.arms = newHeroNode.arms;
    }

    /**
     * 从链表中删除某节点
     * @param no
     */
    public void del(int no){
    
    

        HeroNode temp = head;

        while (true){
    
    

            if(temp.next==null){
    
    
                System.out.println("未找到要删除的节点");
                return;
            }

            if(temp.next.no==no){
    
    
                break;
            }


            temp = temp.next;
        }

        temp.next = temp.next.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.next;
        }
    }
}


class HeroNode{
    
    
    public int no;
    public String name;
    public String arms;
    public HeroNode next;

    public HeroNode(int no, String name, String arms){
    
    

        this.no = no;
        this.name = name;
        this.arms = arms;
    }

    @Override
    public String toString() {
    
    
        return "no:" + no +"  Hero:" + name + "  arms:" + arms;
    }
}

双向链表
在这里插入图片描述

package com.whb.linkedlisk;

public class DoubleLinkedListDemo {
    
    

    public static void main(String[] args) {
    
    

        HeroNode2 h3 = new HeroNode2(3, "周瑜", "火");
        HeroNode2 h1 = new HeroNode2(1, "小乔", "扇子");
        HeroNode2 h2 = new HeroNode2(2, "鲁班", "枪");
        HeroNode2 h4 = new HeroNode2(4, "曹操", "剑");

        DoubleLinkedList link = new DoubleLinkedList();

//        link.add(h1);
//        link.add(h4);
//        link.add(h3);
//        link.add(h2);

        link.addByOrder(h4);
        link.addByOrder(h1);
        link.addByOrder(h3);
        link.addByOrder(h2);

        link.update(new HeroNode2(4, "小曹", "刀"));

//        link.del(3);
//        link.del(1);
//        link.del(4);
//        link.del(2);

        link.list();


    }
}

class DoubleLinkedList{
    
    

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

    public HeroNode2 getHead(){
    
    
        return head;
    }


    // 双向链表的遍历
    public void list(){
    
    
        if(head.next==null){
    
    
            System.out.println("链表为空");
            return;
        }
        HeroNode2 temp = head.next;
        while (true){
    
    
            if(temp==null){
    
    
                break;
            }

            System.out.println(temp);
            temp = temp.next;
        }
    }

    // 添加一个元素到双向链表的最后
    public void add(HeroNode2 heroNode2){
    
    

        HeroNode2 temp = head;

        while (true){
    
    
            if (temp.next==null){
    
    
                break;
            }

            temp = temp.next;

        }


        temp.next = heroNode2;
        heroNode2.pre = temp;
    }

    // 顺序添加
    public void addByOrder(HeroNode2 heroNode){
    
    

        HeroNode2 temp = head.next;
        if(temp==null){
    
    
            head.next = heroNode;
            heroNode.pre = head;
            return;
        }

        while (true){
    
    

            if(temp.no > heroNode.no){
    
      // 找到要插入的位置

                temp.pre.next = heroNode;
                heroNode.pre = temp.pre;
                heroNode.next = temp;
                temp.pre = heroNode;

                break;
            }else if (temp.no == heroNode.no){
    
    
                System.out.println("当前插入英雄的标号为:"+heroNode.no+"  编号已经存在, 插入失败");
                return;
            }else if(temp.next==null){
    
    
                temp.next = heroNode;
                heroNode.pre = temp;
                break;
            }

            temp = temp.next;
        }



    }

    // 修改
    public void update(HeroNode2 newHeroNode){
    
    

        // 判断是否空
        if (head.next == null) {
    
    
            System.out.println("链表为空~");
            return;
        }

        HeroNode2 temp = head.next;
        while (true){
    
    
            if(temp == null){
    
    
                System.out.println("未找到要修改的节点");
                return;
            }

            if(temp.no == newHeroNode.no){
    
    
                break;
            }
            temp = temp.next;
        }

        temp.name = newHeroNode.name;
        temp.arms = newHeroNode.arms;
    }

    // 删除
    public void del(int no) {
    
    

        // 判断当前链表是否为空
        if (head.next == null) {
    
    // 空链表
            System.out.println("链表为空,无法删除");
            return;
        }

        HeroNode2 temp = head.next;
        while (true){
    
    

            if(temp==null){
    
    
                System.out.println("未找到要删除的节点");
                return;
            }

            if(temp.no==no){
    
    
                break;
            }

            temp = temp.next;
        }

        temp.pre.next = temp.next;
        if(temp.next!=null){
    
    
            temp.next.pre = temp.pre;
        }

        temp.pre = null;
        temp.next = null;


    }

}


class HeroNode2{
    
    
    public int no;
    public String name;
    public String arms;
    public HeroNode2 next;
    public HeroNode2 pre;

    public HeroNode2(int no, String name, String arms){
    
    

        this.no = no;
        this.name = name;
        this.arms = arms;
    }

    @Override
    public String toString() {
    
    
        return "no:" + no +"  Hero:" + name + "  arms:" + arms;
    }
}

环形链表解决约瑟夫问题
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

package com.whb.linkedlisk;

public class Josepfu {
    
    

    public static void main(String[] args) {
    
    

        CircleSingleLinkedList c = new CircleSingleLinkedList();
        c.addBoy(5);// 加入5个小孩节点
        c.showBoy();
        System.out.println();

        //测试一把小孩出圈是否正确
        c.countBoy(1, 2);
    }

}

class CircleSingleLinkedList{
    
    

    private Boy first = null;

    // 添加节点
    public void addBoy(int nums){
    
    

        Boy curBoy = null;
        for(int i = 1; i<= nums; i++){
    
    
            Boy boy = new Boy(i);

            if(first==null){
    
    
                first = boy;
                first.setNext(first);
                curBoy = first;
            }else {
    
    
                curBoy.setNext(boy);
                boy.setNext(first);
                curBoy = boy;
            }
        }
    }

    // 遍历
    public void showBoy(){
    
    

        if (first == null){
    
    
            System.out.println("empty");
            return;
        }

        Boy curBoy = first;
        while (true){
    
    
            System.out.printf("小孩的编号 %d \n", curBoy.getNo());
            if(curBoy.getNext()==first){
    
    
                break;
            }
            curBoy = curBoy.getNext();
        }
    }

    // 根据用户的输入, 计算出小孩出圈的顺序

    /**
     *
     * @param startNo 从第几个小孩开始数
     * @param countNum 表示数几下
     */
    public void countBoy(int startNo, int countNum){
    
    

        Boy helper = first;
        while (true){
    
      // 将helper移动到first前面
            if(helper.getNext()==first){
    
    
                break;
            }
            helper = helper.getNext();
        }
        // 让first指针移动到第一个开始报数的小孩的节点,helper指针也跟着移动  (k - 1) 次
        for (int i = 1; i <= startNo - 1; i++){
    
    
            first = first.getNext();
            helper = helper.getNext();
        }

        // first 和 helper 指针同时移动m - 1 次, 然后出圈
        while (true){
    
     // 退出条件,只剩一个
            if(helper==first){
    
    
                break;
            }

            for (int i=1; i<=countNum-1; i++){
    
    

                helper = helper.getNext();
                first = first.getNext();
            }
            System.out.printf("%d出圈\n", first.getNo());
            helper.setNext(first.getNext());
            first = helper.getNext();
        }
        System.out.println("最后的编号:"+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;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_46456049/article/details/112755675
今日推荐