單向循環鏈表基本與單向鏈表相同,惟一的區別就是單向循環鏈表的尾節點指向的不是null,而是頭節點(注意:不是頭指針).
所以,單向循環鏈表的任何節點的下一部分都不存在NULL值。html
因爲單向循環鏈表的特性,它在處理一些環狀數據的時候十分有效.大名鼎鼎的約瑟夫環問題就能夠用循環單向鏈表求解,下面咱們會有進一步的介紹。java
因爲單向循環鏈表和單向鏈表的差異真的不大,增添改查原理都相同。所以在這裏咱們不詳細講解,只提供源碼。(若是你仍是不理解的話,這裏有單向鏈表的傳送門)node
public class Node<Anytype> { public Anytype data; public Node<Anytype> next; public Node(Anytype data,Node<Anytype> next){ this.data=data; this.next=next; } } ------------------------------------ public class SingleLink<AnyType> { //首元節點 public Node<AnyType> first; //頭指針 public Node<AnyType> 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<AnyType> getNode(int i){ Node<AnyType> renode=head; for(int j=-2;j<i;j++){ renode=renode.next; } return renode; } //在末尾添加元素 public void add(AnyType a){ Node<AnyType> 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<AnyType> prev=getNode(i-1); AnyType a=prev.next.data; prev.next=prev.next.next; thesize--; return a; } public void remove2(Node<AnyType> n){ } //在i位置插入新節點 public void insert(int i,AnyType a){ Node<AnyType> prev=getNode(i-1); Node<AnyType> 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<thesize;i++){ System.out.println(getNode(i).data); } } }
聽說著名猶太曆史學家 Josephus有過如下的故事:在羅馬人佔領喬塔帕特後,39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓到,因而決定了一個自殺方式,41我的排成一個圓圈,由第1我的開始報數,每報數到第3人該人就必須自殺,而後再由下一個從新報數,直到全部人都自殺身亡爲止。然而Josephus 和他的朋友並不想聽從。首先從一我的開始,越過k-2我的(由於第一我的已經被越過),並殺掉第k我的。接着,再越過k-1我的,並殺掉第k我的。這個過程沿着圓圈一直進行,直到最終只剩下一我的留下,這我的就能夠繼續活着。問題是,給定了和,一開始要站在什麼地方纔能避免被處決?Josephus要他的朋友先僞裝聽從,他將朋友與本身安排在第16個與第31個位置,因而逃過了這場死亡遊戲。this
首先全部的人是圍城一圈的,並且須要循環不少圈纔可以將全部人依次排除,而這很是適合剛剛完成的單向循環鏈表才解決,尾節點的下一個節點又從新拿到的頭節點,剛剛和問題中的狀況契合。
首先咱們只要拿到鏈表的頭節點,而後依次經過頭節點的next指針日後拿到下一個節點,找到第3個移除鏈表,而後依次循環直到鏈表爲空,移除的順序就是咱們須要的死亡順序。spa
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<Integer> sl=new SingleLink<>(); sl.initlist(); //編號add進鏈表 for(int i=0;i<sum;i++){ sl.add(i+1); } Node<Integer> n=sl.first; while(n.next!=n){ for(int i=1;i<space;i++){ n=n.next; } int a=n.next.data; n.next=n.next.next; s=s+a+","; } System.out.println(s); } } /* 輸入:41 3 輸出:3,6,9,12,15,18,21,24,27,30,33,36,39,1,5,10,14,19,23,28,32,37,41,7,13,20,26,34,40,8,17,29,38,11,25,2,22,4,35,16, */