52

问答题 52 /69

约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。写程序实现上述过程。

参考答案

#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
    int num;
    struct Node *next;
} LinkList;
LinkList *creat(int n)
{
    LinkList *p, *q, *head;
    int i = 1;
    p = (LinkList *)malloc(sizeof(LinkList));
    p->num = i;
    head = p;
    for (i = 2; i <= n; i++)
    {
        q = (LinkList *)malloc(sizeof(LinkList)); /*Malloc()向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。*/
        q->num = i;
        p->next = q;
        p = q;
    }
    p->next = head;        /*使链表尾指向链表头 形成循环链表*/
    return head;
}
void fun(LinkList *L, int m)
{
    int i;
    LinkList *p, *s, *q;
    p = L;
    printf("出列顺序为:");
    while (p->next != p)
    {
        for (i = 1; i < m; i++) /*从1开始*/
        {
            q = p;
            p = p->next;
        }
        printf("%5d", p->num);
        s = p;
        q->next = p->next;
        p = p->next; /*使p指向新的起点*/
        free(s);/*free()与malloc()函数配对使用,释放malloc函数申请的动态内存*/
    }
    printf("%5d\n", p->num);
}
int main()
{
    LinkList *L;
    int n, m;
    n = 9;
    m = 5;
    L = creat(n);
    fun(L, m);
    return 0;
}