Josephus(约瑟夫)问题

一群小孩围成一圈,任意假定一个数m,从第一个小孩数起,数到第m个的时候,该小孩离开,依次这样数下去,最后一个小孩是胜利者,问:胜利者是第几个小孩?

单向循环列表实现

#include <stdio.h>
#include <assert.h>

#define N 8

typedef struct _LIST {
int data;
struct _LIST *next;
} LIST;

inline void list_init(LIST *node,int data,LIST *next) {
node->data = data;
node->next = next;
}

int josephus(LIST *head,int m) {
int i;
LIST *t=head;

while(1) {
for(i=0;i<m-2;i++) {
head = head->next;
}
t = head;
if(t->next==t) {
break;
} else {
t->next = t->next->next;
}
head = head->next;
}

return t->data;
}


int main(int argc, char *argv[]) {
LIST boys[N];// 使用数组避免手工分配和释放内存
list_init(boys+7,8,boys+0);
list_init(boys+6,7,boys+7);
list_init(boys+5,6,boys+6);
list_init(boys+4,5,boys+5);
list_init(boys+3,4,boys+4);
list_init(boys+2,3,boys+3);
list_init(boys+1,2,boys+2);
list_init(boys+0,1,boys+1);
// 3 6 1 5 2 8 4 7
assert(josephus(boys,3)==7);

return 0;
}

注:可以修改程序,在josephus函数里面打印出列的人。

面向对象方式实现

主要是实现一个单向循环链表。

 

posted @ 2011-12-18 10:28  pingjiang  阅读(435)  评论(3编辑  收藏  举报