zoukankan      html  css  js  c++  java
  • 五、单项环形链表

    单项环形链表

    约瑟夫环问题

    设编号为1,2,3,...n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,他的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

    思路:

    用一个不带头结点的循环链表来处理约瑟夫问题:先构成一个有n个节点单项环形链表,然后由k节点起从1开始计数,到m时,把对应节点从链表中删除,然后再从被删除节点的下一个节点开始从1计数,知道最后一个节点从链表中删除算法结束。

    代码示例:

    public class Josepfu {
        public static void main(String[] args) {
            SingleCircleLinkedList singleCircleLinkedList = new SingleCircleLinkedList();
            singleCircleLinkedList.Josepfu(1, 2, 5);
        }
    }
    
    //创建单项环形链表
    class SingleCircleLinkedList {
        //创建一个first节点,当前没有编号
        private Node first;
    
        /**
         * @param nums 为环形链表添加几个节点
         */
        public void createSingleCircleLinkedList(int nums) {
            if (nums < 1) {
                System.out.println("nums值不正确");
                return;
            }
            Node curNode = null;
            for (int i = 1; i <= nums; i++) {
                //根据编号创建节点
                Node node = new Node(i);
                if (i == 1) {
                    first = node;
                    first.setNext(first);//构成环
                    curNode = first;//让curNode指向第一个节点
                } else {
                    curNode.setNext(node);
                    node.setNext(first);
                    curNode = node;
                }
            }
        }
    
        /**
         * 遍历当前环形链表
         */
        public void list() {
            if (first == null) {
                throw new RuntimeException("链表为空!");
            }
            Node curNode = first;
            while (true) {
                System.out.println(curNode);
                if (curNode.getNext() == first) {
                    break;
                }
                curNode = curNode.getNext();
            }
        }
    
        /**
         * 根据用户的输入来完成约瑟夫环问题
         *
         * @param startNo  表示从编号几开始数
         * @param countNum 表示数几下
         * @param nums     表示最初有几个人
         */
        public void Josepfu(int startNo, int countNum, int nums) {
            if (nums < 1 || startNo < 1 || startNo > nums) {
                throw new RuntimeException("参数输入有误!");
            }
            createSingleCircleLinkedList(nums);
            Node pre = first;
            //使pre指向first节点的前一个节点
            while (true) {
                if (pre.getNext() == first) {
                    break;
                }
                pre = pre.getNext();
            }
            //使first和pre先移动到一开始报数的人那里
            for (int i = 0; i < startNo - 1; i++) {
                first = first.getNext();
                pre = pre.getNext();
            }
            //当第一个人开始报数时,让first和pre指针同时开始移动countNum-1此,然后first指向的节点出圈
            while (true) {
                if (first == pre) {
                    break;
                }
                for (int i = 0; i < countNum - 1; i++) {
                    first = first.getNext();
                    pre = pre.getNext();
                }
                //这时first指向的节点就是要出圈的节点
                System.out.println(first);
                first = first.getNext();
                pre.setNext(first);
            }
            //退出循环后,圈中就只剩下一个节点了。
            System.out.println(first);
        }
    }
    
    class Node {
        private int no;
    
        private Node next;
    
        public Node(int no) {
            this.no = no;
        }
    
        public int getNo() {
            return no;
        }
    
        public void setNo(int no) {
            this.no = no;
        }
    
        public Node getNext() {
            return next;
        }
    
        public void setNext(Node next) {
            this.next = next;
        }
    
        @Override
        public String toString() {
            return "Node{" +
                    "no=" + no +
                    '}';
        }
    }
    
  • 相关阅读:
    APK中java代码反编译
    android应用分析之apk文件结构
    2016第8周五
    优秀前端需要具备的经验
    postgreSQL数据类型转换字符串和数值
    架构设计要考虑的几个方面
    2016第8周一
    常见的交互设计方法
    开源项目使用经验原则
    ExtJS与JQuery对照
  • 原文地址:https://www.cnblogs.com/lee0527/p/12018863.html
Copyright © 2011-2022 走看看