片方向循環リストとは何ですか
実質的に円形のリスト一方向道リンクリスト同じことが、唯一の違いは、円形のリストは、エンドノードヌルを指していないようであるが、ヘッドノード。(注:ポインタを頭ない)
円形のリストを、このように一方向の任意のノードを一部には、NULL値が存在しません。
片方向循環リストの性質のために、それはリング。ジョセフ・中部の有名な問題は、一方向の循環リストによって解決することができ、データの一部に対処するのに非常に効果的である、ここではさらに導入しています。
一方向と一方向循環リンクリストリンクリストの違いは本当に小さいですし、検索の原則は同じで変更することが追加されます。そこでここでは、唯一の利用可能なソース、詳細に説明しません。(あなたはまだ言葉を理解していない場合があり、片方向リンクリストポータルの)
ソース実装(Javaの)
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);
}
}
}
アプリケーションの片道循環リスト----ヨセフスの問題
問題の起源
有名なユダヤ人の歴史家ヨセフスは、次の物語を持っていたと言われて:Qiaotapate、39人のユダヤ人とヨセフスと彼の友人が洞窟に隠れ、ローマ占領した後、39人のユダヤ人は、むしろ死んでしまう決めて、敵を巻き込まないでくださいそして自殺、円形に配置された41人の個人、最初の個人的なCountinを決め、すべての3番目の数字は、すべての自殺まで、新聞による再カウント、その後、自殺を持っている人に報告しましたこれまでに死亡しました。しかし、ヨセフスと彼の友人は従わたくありませんでした。個々のk-2(最初の男が逆になっているため)を超えて、人と起動し、k個の個人を殺します。次に、K-1、次いで、個々の上、及びk番目の個体を殺します。最終的には唯一の次の人は残すようになるまでのプロセスは、円の周り続けて、この人は生き続けることができます。問題は、与えられたと、実行を避けるために、どこかに立って始めて、ということでしょうか?ヨセフスは、彼の友人は、彼が16と31の位置にある彼の友人で手配いたし遵守するふりをしたかったのは、この死のゲームを脱出しました。
アイデア解析
まず、すべての人々のヘッドノードを取得するために、再び包囲の輪で、そして誰を排除するために周回多くのサイクルにできるようにする必要があり、完了したばかりの片方向循環リストが解決されたことが理想的である、次のノードのエンド・ノードただ問題とフィット感の場合には
まず、限り、私たちは、リストの最初のノードを取得し、その後3は、リストが空になるまでのサイクルに続いて、リストを削除するには見つけ、次のヘッドノードで次のノードポインタを取得するために引き返すよう、取り外し順序は、私たちが必要とするものです死の順番。
ソース実装(ここでは、一方向の循環リストは、私たちが-SingleLink上記の達成ということです)
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,
*/