约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后 结果+1即为原问题的解。

中文名

约瑟夫问题

外文名

Joseph problem

其他命名

约瑟夫环、丢手绢问题

学科

数学

别名

约瑟夫斯置换

算法原理

约瑟夫环运作如下:

1、一群人围在一起坐成环状(如:N)

2、从某个编号开始报数(如:K)

3、数到某个数(如:M)的时候,此人出列,下一个人重新报数

4、一直循环,直到所有人出列,约瑟夫环结束

算法例子

C#

C语言

递归法

非递归法:

C++非递归实现(模拟实现)

C++数列推导实现(数学推导式)

Java实现

Common Lisp递归实现

(defun josephus-main )

(let (lt (make-array 20 :fill-pointer 0)

(dotimes (var 20)

(vector-push var lt)

(josephus-loop lt)

(defun josephus-loop(lt)

(if (= (length lt) 1)

(progn

(format t "~a~%" lt)

(return-from josephus-loop)

(if (>= (length lt) 5)

(progn

(let (setv (remove (elt lt 4)lt)

(josephus-loop setv)

(progn

(let (setv (remove (elt lt (if (= (length lt) (- 4 (length lt) (- 4 (length lt) 1) (- 4 (length lt) lt)

(josephus-loop setv)

pascal

program Josephus(input,output);

type pointer=^nodetype;

nodetype=record

data:integer;

link:pointer

end;

var head,next,last:pointer;

i,n,s,j,m,k:integer;

begin

writeln('请输入组成约瑟夫环的人数:');

read(n);

new(head);

head^.data :=1;

last:=head;

for

to n do

begin

new(next);

next^.data :=i;

last^.link :=next;

last:=next

end;

last^.link :=head;

next:=head;

repeat

begin

writeln(next^.data);

next:=next^.link

end;

until next=head;

readln;

next:=head;

writeln('请输入第一个报数人的位置:');

read(s);

;

if s<=n

then

while j

begin

next:=next^.link ;

end

else writeln('你的输入有误');

writeln('请输入出列人的位置:');

read(m);

while next^.link <>next do

begin

;

while k

begin

last:=next;

next:=next^.link ;

end;

writeln(next^.data);

last^.link :=next.link ;

next:=next^.link

end;

writeln(next^.data);

readln;

readln

end.

python实现

JavaScript

php