约瑟夫环问题
Posted peiyao456
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了约瑟夫环问题相关的知识,希望对你有一定的参考价值。
约瑟夫环问题就是从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开
始报数,数到m的那个人又出列;计算出最后留下来的那个人的编号。
下边给出两种方法,顺序表实现和链表实现。
链表的代码:
typedef struct LinkNode { DataType data; struct LinkNode *next; }LinkNode,*pLinkNode; typedef struct LinkList { LinkNode *pHead; }LinkList,*pLinkList; pLinkNode JosephCircle(pLinkList pList,int k,int m)//从k开始计数,数到m出列 { assert(pList); if (NULL == pList->pHead) { printf("空链表\n"); return NULL; } pLinkNode cur = pList->pHead; pLinkNode del = NULL; while (--k) { cur = cur->next; } while (cur->next != cur) { int tmp = m; while (--tmp) { cur = cur->next; } printf("要删除的元素是%d\n",cur->data); del = cur->next; cur->data = cur->next->data; cur->next = cur->next->next; free(del); } return cur; }
顺序表代码:
#define _CRE_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<malloc.h> void Joscircle(int n, int k, int m) { int *p = (int *)malloc(n*sizeof(int)); int i = 0; int out = 0; int count = 0;//用来计数,当count达到m时,所数到的人出列 for (i = 0;i < n;i++) { *(p + i) = 1;//所有的人都被赋值为1,要是有人出列,将其值改为0 } i = k - 1;// while (out != n - 1) { if (p[i] == 1)//如果该人所在的位置为1,说明此人还在队伍中,计数时就可以包括他 count++; if (count == m)//如果数到某个人时,count刚好为m,此时,此人出列,将其所对应的数改为0 { p[i] = 0; count = 0; out++;//出伍的人数加1 } i++; if (i == n)//由于总共n个人,数组下标的i从0到n-1,如果数到n,我们就将其置为0 { i = 0; } } for (i = 0;i < n;i++) { if (p[i])//那个没有被改为0的数对应的人就是最终没有出列的人 { printf("第%d个人最终没有出列",i+1); } } free(p); } int main() { Joscircle(10,2,3);//10个人围成一圈,从第二个人开始数数,数到3的那个人出列 system("pause"); return 0; }
以上是关于约瑟夫环问题的主要内容,如果未能解决你的问题,请参考以下文章