约瑟夫环_循环单链表

来源:互联网 发布:win7 无法连接到网络 编辑:程序博客网 时间:2024/05/29 13:12
/*
 * 问题描述:
 *     编号为1,2,...,n 的n 个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
 *     一开始任选一个正整数作为报数上限值 m,从第一个人开始。按顺时针方向自 1 开始顺序报数,报到m 时停止报数。
 *     报m的人出列,将他的密码作为新的m 值, 从他在顺时针方向上的下一个人开始重新从1 报数,如此下去,直至所有人全部出列为止。
 */


/*
 * 思路分析:
 *     1、将人的顺序编号,从1到n
 *     2、将人的编号存到结点的num域
 *     3、将人的密码存到结点的pas域
 *     4、构造一个带头结点的循环链表,解决首尾相连的问题
 *     5、开始报数,从头报数,报到m的人出局,释放该结点。直到人数只有一个人时,退出循环。输出获胜的人。

 */

//// Created by Admin on 2017/3/30.//#include <cstdio>#include <malloc.h>//定义结点typedef struct node{    int num;    int pas;    struct node *next;}JosephNode;typedef JosephNode *CircularList;//初始化循环链表为空表void InitList(CircularList &first){    first=(JosephNode *)malloc(sizeof(JosephNode));    first->next=first;}//存储每个人的编号和密码void InputData(CircularList &first,int n){    int temp;    printf("请输入每个人的密码(以空格分隔):");    CircularList newnode,p=first;    for (int i = 1; i <= n; ++i) {        scanf("%d",&temp);        newnode=(JosephNode *)malloc(sizeof(JosephNode));  //创建结点        if(!newnode)exit(0);        newnode->num=i; //存储编号        newnode->pas=temp;  //存储出局密码        //插入到链尾        p->next=newnode;        p=newnode;    }    p->next=first;  //将链尾连接头结点}//遍历链表void TravelList(CircularList first){    CircularList p=first->next;    while(p!=first){        printf("\tnum: %d\t\tpas: %d\n",p->num,p->pas);        p=p->next;    }}//testing//solvevoid Solve(CircularList &first,int n,int m){    CircularList p=first;    int count=1; //count用于控制输出格式    while (n--){        int i=1;  //i为计数器        while(i<m){  //找到第m-1个结点            if(p->next==first)p=p->next; //如果下一个结点为头结点,则跳过头结点,计数器不自增            else{  //否则计数+1,并且指向下一个结点                p=p->next;                i++;            }        }//循环结束后,p为第m-1个结点        if(p->next==first)p=p->next; //判断下一个是否为头结点,是则跳过头结点        printf("num= %d\t",p->next->num);  //输出第m个结点的标号        if(n==0)printf("\n\n\tThe Winner is : %d",p->next->num);        else{            if(count%5==0)printf("\n");            count++;        }        m=p->next->pas;  //更新m值        //删除第m个结点        CircularList q=p->next;        p->next=q->next;        free(q);    }    printf("\n\n");}int main(){    char op;    int n,m;    CircularList first;    printf("输入Y/y进入操作!\n");    while (~scanf("%c",&op)){        if(op=='n'||op=='N')break;        else{            system("cls");            InitList(first);            printf("请输入参与人数:");            scanf("%d",&n);            printf("请输入初始出局密码:");            scanf("%d",&m);            InputData(first,n);            printf("\n/****************testing*****************/\n");            printf("/****************数据存储****************/\n");            TravelList(first);            printf("\n/****************出列顺序****************/\n");            Solve(first,n,m);        }        printf("输入Y/N,继续操作:\n");        getchar();    }    return 0;}


特殊数据已测试



0 0
原创粉丝点击