循环链表---猴子选大王

来源:互联网 发布:260工程数据 编辑:程序博客网 时间:2024/05/13 23:19

ZT

文章作者:Slyar 文章来源:Slyar Home (www.slyar.com) 转载请注明,谢谢合作

 

 

题目描述:n只猴子要选大王,选举方法如下:所有猴子按 1,2 ……… n 编号并按照顺序围成一圈,从第 k 个猴子起,由1开始报数,报到m时,该猴子就跳出圈外,下一只猴子再次由1开始报数,如此循环,直到圈内剩下一只猴子时,这只猴子就是大王。

输入数据:猴子总数n,起始报数的猴子编号k,出局数字m

输出数据:猴子的出队序列和猴子大王的编号

 

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
/*约瑟夫问题(猴子选大王)循环链表C语言实现Slyar 2009.3.31http://www.slyar.com*/ #include <stdio.h>#include <stdlib.h> /* 定义链表节点类型 */typedef struct node{    int data;    struct node *next;}linklist; int main(){    int i, n, k, m, total;    linklist *head, *p, *s, *q;    /* 读入问题条件 */    printf("请输入猴子的个数:");    scanf("%d", &n);    printf("请输入要从第几个猴子开始报数:");    scanf("%d", &k);    printf("请输入出局数字:");    scanf("%d", &m);    /* 创建循环链表,头节点也存信息 */    head = (linklist*) malloc(sizeof(linklist));    p = head;    p->data = 1;    p->next = p;    /* 初始化循环链表 */    for (i = 2; i <= n; i++)    {        s = (linklist*) malloc(sizeof(linklist));        s->data = i;        s->next = p->next;        p->next = s;        p = p->next;    }    /* 找到第 k 个节点 */    p = head;    for (i = 1; i < k; i++)    {        p = p->next;    }    /* 保存节点总数 */    total = n;    printf("/n出局序列为:");    q = head;    /* 只剩一个节点时停止循环 */    while (total != 1)    {        /* 报数过程,p指向要删除的节点 */        for (i = 1; i < m; i++)        {            p = p->next;        }        /* 打印要删除的节点序号 */        printf("[%d] ", p->data);        /* q 指向 p 节点的前驱 */        while (q->next != p)        {            q = q->next;        }        /* 删除 p 节点 */        q->next = p->next;        /* 保存被删除节点指针 */        s = p;        /* p 指向被删除节点的后继 */        p = p->next;        /* 释放被删除的节点 */        free(s);        /* 节点个数减一 */        total--;    }    /* 打印最后剩下的节点序号 */    printf("/n/n猴子大王为第 [%d] 号/n/n", p->data);    free(p);    //system("pause");    return 0;}