(java实现)单向循环链表

什么是单向循环链表

单向循环链表基本与单向链表相同,唯一的区别就是单向循环链表的尾节点指向的不是null,而是头节点(注意:不是头指针).
因此,单向循环链表的任何节点的下一部分都不存在NULL值。

(java实现)单向循环链表_第1张图片

由于单向循环链表的特性,它在处理一些环状数据的时候十分有效.大名鼎鼎的约瑟夫环问题就可以用循环单向链表求解,下面我们会有进一步的介绍。

由于单向循环链表和单向链表的差别真的不大,增添改查原理都相同。因此在这里我们不详细讲解,只提供源码。(如果你还是不理解的话,这里有单向链表的传送门)


源码实现(Java)

public class Node {
    public Anytype data;
    public Node next;
    public Node(Anytype data,Node next){
        this.data=data;
        this.next=next;
    }
}

------------------------------------

public class SingleLink {


    //首元节点
    public Node first;

    //头指针
    public Node head;

    //链表长度
    int thesize;

    //初始化链表
    public boolean initlist(){
        thesize=0;
        first=new Node<>(null,null);
        head=new Node<>(null,first);
        first.next=head;
        return true;
    }

    //判断链表是否为空
    public boolean isEmpty(){
        return thesize==0;
    }

    //获取节点
    public Node getNode(int i){
        Node renode=head;
        for(int j=-2;j renode=new Node<>(a,null);
        getNode(thesize-1).next=renode;
        renode.next=first.next;
        thesize++;
    }

    //删除i位置节点,并返回删掉的数据
    public AnyType remove(int i){
        if(i==thesize-1){
            AnyType a=getNode(thesize-1).data;
            getNode(thesize-2).next=first.next;
            return a;
        }
        Node prev=getNode(i-1);
        AnyType a=prev.next.data;
        prev.next=prev.next.next;
        thesize--;
        return  a;
    }

    public void remove2(Node n){

    }

    //在i位置插入新节点
    public void insert(int i,AnyType a){
        Node prev=getNode(i-1);
        Node renode=new Node<>(a,prev.next);
        prev.next=renode;
        thesize++;
    }

    //获取i位置节点的数据
    public AnyType get(int i){
        return getNode(i).data;
    }

    //为i位置元素重新赋值
    public void set(int i,AnyType a){
        getNode(i).data=a;
    }

    //返回链表节点个数
    public int length(){
        return thesize;
    }

    //清空链表
    public void clear(){
        initlist();
    }

    //打印链表
    public void print(){
        for(int i=0;i

单向循环链表的应用----约瑟夫环问题

问题来历

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。

思路分析

首先所有的人是围城一圈的,而且需要循环很多圈才能够将所有人依次排除,而这非常适合刚刚完成的单向循环链表才解决,尾节点的下一个节点又重新拿到的头节点,刚刚和问题中的情况契合。
首先我们只要拿到链表的头节点,然后依次通过头节点的next指针往后拿到下一个节点,找到第3个移除链表,然后依次循环直到链表为空,移除的顺序就是我们需要的死亡顺序。

import java.util.Scanner;

public class JosephRing {
    public static void main(String[] args){
        int sum=0;
        int space=0;
        String s="";
        System.out.println("输入环数和间隔");
        Scanner sc=new Scanner(System.in);
        sum=sc.nextInt();
        space=sc.nextInt();
        SingleLink sl=new SingleLink<>();
        sl.initlist();
        //编号add进链表
        for(int i=0;i n=sl.first;
        while(n.next!=n){
            for(int i=1;i

你可能感兴趣的:((java实现)单向循环链表)