约瑟夫环

一、思路分析

    (1)可将人的顺序简单编号,从1到N;

    (2)构造一个循环链表,可以解决首位相连的问题,同时如果将人的编号改为人名或者其他比较方便

         (3)将人的编号插入到结构体的Data域;

         (4)遍历人的编号,输出参与的人的编号;

         (5)开始报数,从头报数,报到k的人出局(删除次结点),(输出出局的人更人性化)避免浪费,可释放次结点。直到人数只有一个人时,退出循环。输出获胜的人。

   (6)注意:在写删除删除结点的函数时都是针对K>=2的情况处理,所以要考虑k=1的情况,要是出局的密码为1时则最后一个获胜。


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <malloc.h>  
  3.   
  4. /*构建结构体*/  
  5. typedef struct Node{  
  6.     int Num;  
  7.     struct Node *next;  
  8. }JoseNode, *PNode, *HNode;  
  9.   
  10. /**********初始化循环单链表*********/  
  11. int JoseInit(HNode *h)  
  12. {  
  13.     if (!h)  
  14.     {  
  15.         printf("初始化链表错误!\n");  
  16.         return 0;  
  17.     }  
  18.     (*h)->next = (*h);//循环单链表  
  19.     return 1;  
  20.   
  21. }  
  22.   
  23. /*************单链表插入操作**********/  
  24. int JoseInsert(JoseNode *h, int pos, int x)  
  25. {      
  26.     PNode p=h,q;  
  27.     int i=1;  
  28.     if (pos == 1)/*尾插法*/  
  29.     {  
  30.         p->Num = x;  
  31.         p->next = p;  
  32.         return 1;  
  33.     }  
  34.     while(i<pos-1)  
  35.     {  
  36.         p=p->next;  
  37.         i++;  
  38.     }  
  39.     q=(PNode)malloc(sizeof(JoseNode));  
  40.     q->Num=x;  
  41.     q->next=p->next;  
  42.     p->next=q;  
  43.     return 1;  
  44. }  
  45.   
  46. /*遍历*/  
  47. void TraverseList(HNode h, int M)  
  48. {  
  49.     int i = 0;  
  50.     PNode p = h;  
  51.     printf("参与的人的编号为:\n");  
  52.     while (i<M)  
  53.     {  
  54.         printf("%d\t", p->Num);  
  55.         p = p->next;  
  56.         i++;  
  57.     }  
  58.     printf("\n");  
  59. }  
  60. /**************出局函数****************/  
  61.   
  62. int JoseDelete(HNode h, int M, int k)  
  63. {    int i;  
  64.     PNode p=h,q;  
  65.     while(M>1)  
  66.     {  
  67.         for(i=1;i<k-1;i++)  
  68.         {  
  69.             p=p->next;  
  70.         }  
  71.           
  72.         q=p->next;  
  73.         p->next=q->next;  
  74.         printf("出局的人为:%d号\n",q->Num);  
  75.         free(q);  
  76.   
  77.         p=p->next;  
  78.         M--;  
  79.     }  
  80.     printf("***************获胜者为:%d号***************",p->Num);  
  81.     return 1;  
  82. }  
  83.   
  84.   
  85. /***************************************/  
  86. int main()  
  87. {  
  88.     int i;//计数器  
  89.     int N;//参与的人数  
  90.     int k;//报数密码  
  91.     printf("请输入参与人数:");  
  92.     scanf("%d",&N);  
  93.     printf("请输入出局密码:");  
  94.     scanf("%d",&k);  
  95.   
  96. /**************得到头结点****************/  
  97.     HNode h = ((HNode)malloc(sizeof(JoseNode)));  
  98.   
  99. /***************初始化单链表************/  
  100.     JoseInit(&h);  
  101.   
  102. /******将编号插入到循环单链表中******/  
  103.     for (i = 1; i <=N; i++)  
  104.     {  
  105.         JoseInsert(h, i, i);  
  106.     }  
  107. /**************遍历单链表***************/  
  108.     TraverseList(h,N);  
  109.   
  110. /***************出局函数************/  
  111.     if(k > 1)  
  112.     JoseDelete(h, N, k);  
  113.     else  
  114.     {  
  115.         for(i = 1; i < N; i++)  
  116.             printf("出局的人为:%d号\n",i);  
  117.         printf("***************获胜者为:%d号***************",N);  
  118.     }  
  119.   
  120.     printf("\n");  
  121.     printf("\n");  
  122.     return 0;  
  123. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值