约瑟夫环问题可以简单的使用数组的方式实现,但是现在我使用循环链表的方法来实现,因为上午看到一道面试题规定使用循环链表解决约瑟夫环问题。
什么是约瑟夫环?
“约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。”(百度百科中的解决办法列出了很多,可以看到循环链表并不是最简单的方法)
这道面试题考察了循环链表的“创建”,“遍历”和“删除”。
创建的循环链表的结构图:
解决约瑟夫环问题的过程
#include<iostream> using namespace std; struct ele { int no; struct ele *link; } main() { struct ele *h, *u, *p; int n, m, i;
printf("Please input n&m: ");
scanf("%d%d", &n, &m);/*输入n和m*/ h = u = (struct ele *) malloc(sizeof(struct ele));/*形成首表元*/ h->no = 1; for (i = 2; i <= n; i++)/*形成其余的n-1个表元*/ { u->link = (struct ele *) malloc(sizeof(struct ele)); u = u->link; u->no = i;/*第i个表元置编号i*/ } u->link = h;/*末表元后继首表元,形成环*/
puts(" The numbers of who will quit the cycle in turn are:");
while (n) { for (i = 1; i < m; i++) /*掠过m-1个表元*/ u = u->link; p = u->link;/*p指向第m个表元*/ u->link = p->link;/*第m个表元从环中脱钩*/ printf("%4d", p->no); free(p);/*释放第m个表元占用的空间*/ n--; } printf(" Press any key to quit... "); getchar(); }