一、思路分析
(1)可将人的顺序简单编号,从1到N;
(2)构造一个循环链表,可以解决首位相连的问题,同时如果将人的编号改为人名或者其他比较方便
(3)将人的编号插入到结构体的Data域;
(4)遍历人的编号,输出参与的人的编号;
(5)开始报数,从头报数,报到k的人出局(删除次结点),(输出出局的人更人性化)避免浪费,可释放次结点。直到人数只有一个人时,退出循环。输出获胜的人。
(6)注意:在写删除删除结点的函数时都是针对K>=2的情况处理,所以要考虑k=1的情况,要是出局的密码为1时则最后一个获胜。
- #include <stdio.h>
- #include <malloc.h>
-
-
- typedef struct Node{
- int Num;
- struct Node *next;
- }JoseNode, *PNode, *HNode;
-
-
- int JoseInit(HNode *h)
- {
- if (!h)
- {
- printf("初始化链表错误!\n");
- return 0;
- }
- (*h)->next = (*h);
- return 1;
-
- }
-
-
- int JoseInsert(JoseNode *h, int pos, int x)
- {
- PNode p=h,q;
- int i=1;
- if (pos == 1)
- {
- p->Num = x;
- p->next = p;
- return 1;
- }
- while(i<pos-1)
- {
- p=p->next;
- i++;
- }
- q=(PNode)malloc(sizeof(JoseNode));
- q->Num=x;
- q->next=p->next;
- p->next=q;
- return 1;
- }
-
-
- void TraverseList(HNode h, int M)
- {
- int i = 0;
- PNode p = h;
- printf("参与的人的编号为:\n");
- while (i<M)
- {
- printf("%d\t", p->Num);
- p = p->next;
- i++;
- }
- printf("\n");
- }
-
-
- int JoseDelete(HNode h, int M, int k)
- { int i;
- PNode p=h,q;
- while(M>1)
- {
- for(i=1;i<k-1;i++)
- {
- p=p->next;
- }
-
- q=p->next;
- p->next=q->next;
- printf("出局的人为:%d号\n",q->Num);
- free(q);
-
- p=p->next;
- M--;
- }
- printf("***************获胜者为:%d号***************",p->Num);
- return 1;
- }
-
-
-
- int main()
- {
- int i;
- int N;
- int k;
- printf("请输入参与人数:");
- scanf("%d",&N);
- printf("请输入出局密码:");
- scanf("%d",&k);
-
-
- HNode h = ((HNode)malloc(sizeof(JoseNode)));
-
-
- JoseInit(&h);
-
-
- for (i = 1; i <=N; i++)
- {
- JoseInsert(h, i, i);
- }
-
- TraverseList(h,N);
-
-
- if(k > 1)
- JoseDelete(h, N, k);
- else
- {
- for(i = 1; i < N; i++)
- printf("出局的人为:%d号\n",i);
- printf("***************获胜者为:%d号***************",N);
- }
-
- printf("\n");
- printf("\n");
- return 0;
- }