美文网首页
4.链表部分练习题

4.链表部分练习题

作者: 据分专家 | 来源:发表于2020-10-07 15:18 被阅读0次

1.约瑟夫问题

约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3。

本题可使用循环链表解决
设置一个节点firsthead指向被删除节点
一个helper节点指向被删除节点的前一个节点
在下列代码中
在构建循环链表时,firsthead.next=第一个节点
在游戏开始时,需要使得firsthead=第一个节点

package com.zhiyang.linkedlist;

public class Josepfu {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        CircleLinkedList circleLinkedList = new CircleLinkedList();
        circleLinkedList.addBoy(5);
        // circleLinkedList.showList();
        circleLinkedList.countBoy(1, 2, 5);

    }

}

class CircleLinkedList {
    private Boy firsthead = null;

    public void addBoy(int n) {
        firsthead = new Boy(-1);
        if (n < 1) {
            System.out.println("人数过少");
            return;
        }
        Boy curBoy = firsthead;
        for (int i = 1; i <= n; i++) {
            Boy boy = new Boy(i);
            curBoy.next = boy;
            boy.next = firsthead.next;
            curBoy = curBoy.next;
        }
    }

    // 遍历环形链表
    public void showList() {
        if (firsthead == null) {
            return;

        }

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

    }

    // 根据用户输入,计算小孩出圈顺序
    /**
     * 
     * <p>
     * Title: countBoy
     * </p>
     * <p>
     * Description:
     * </p>
     * void
     * 
     * @param startno  从第几个小孩开始
     * @param countNum 数几个出圈
     * @param nums     总共多少人
     */
    public void countBoy(int startno, int countNum, int nums) {
        if (firsthead == null || startno < 1 || startno > nums) {
            System.out.println("参数错误");
            return;
        }

        // 创建一个辅助指针,帮助完成小孩出圈
        Boy helperBoy = firsthead.next;
        while (true) {
            if (helperBoy.next == firsthead.next) {
                break;
            }
            helperBoy = helperBoy.next;
        }
        // 现在helperBoy=队列最后一个
        // 出圈前,需要先移动到statrno位置来
        System.out.printf("目前helper指向的节点是%d\n", helperBoy.getNo());
        System.out.printf("目前firsthead指向的节点是%d\n", firsthead.getNo());
        firsthead = firsthead.next;
        for (int j = 0; j < startno - 1; j++) {
            firsthead = firsthead.next;
            helperBoy = helperBoy.next;
        }
        System.out.printf("目前helper指向的节点是%d\n", helperBoy.getNo());
        System.out.printf("目前firsthead指向的节点是%d\n", firsthead.getNo());
        while (true) {
            if (helperBoy == firsthead) {
                break;
            }
            for (int j = 0; j < countNum - 1; j++) {
                firsthead = firsthead.next;
                helperBoy = helperBoy.next;
            }
            // 这是first指向的小孩就是要出圈的小孩
            System.out.printf("小孩%d出圈\n", firsthead.getNo());
            firsthead = firsthead.next;
            helperBoy.next = firsthead;
        }
        System.out.printf("最后留在圈中的小孩的节点%d", firsthead.getNo());
    }
}

class Boy {
    private int no;
    public Boy next;

    public Boy(int no) {
        super();
        this.no = no;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

}

目前helper指向的节点是5
目前firsthead指向的节点是-1
目前helper指向的节点是5
目前firsthead指向的节点是1
小孩2出圈
小孩4出圈
小孩1出圈
小孩5出圈
最后留在圈中的小孩的节点3

相关文章

  • 4.链表部分练习题

    1.约瑟夫问题 约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都...

  • python 链表结构练习

    链表结构练习题: https://leetcode-cn.com/problems/add-two-numbers...

  • 4. 链表

    链表题目是有套路的,如下4个方法: 链表逆序 (n个节点进行逆序,实际上循环进行n-1次)2个指针 (拆分、拼接、...

  • 两数相加,针对ListNode的练习

    创建ListNode 1.给链表赋值: 2.从链表中取值: 经典练习题: 2. 两数相加[https://leet...

  • C语言练习题: 函数部分

    C语言练习题:函数部分(9题) 上一篇: C语言练习题:循环部分 下一篇: C语言练习题:数组部分 斐波那契,函数...

  • C语言练习题:循环部分

    C语言练习题:循环部分(20题) 上一篇: C语言练习题:if语句部分 下一篇: C语言练习题:函数部分 求一正整...

  • 2020-11-07

    练习题 1. 2. 3. 4. 解答过程

  • 双向链表于双向循环链表的终结

    一、双向链表: 1.双向链表的创建:如图 2.双向链表的输出: 3.双向链表的插入: 4.双向链表的删除: 二、双...

  • 关于线性表算法题的练习(上)

    学习了这么多的链表结构和链表原理,是时候做一些练习题了,废话不多说,直接上代码。 题目1:将2个递增的有序链表合并...

  • 8.单向链表SingleLinkList

    目录:1.单向链表的定义2.单向链表的图解3.单向链表定义操作4.单向链表的实现 1.单向链表的定义 2.单向链表...

网友评论

      本文标题:4.链表部分练习题

      本文链接:https://www.haomeiwen.com/subject/mmvfpktx.html