约瑟夫环问题

来源:互联网 发布:怎么在mac上玩lolsteam 编辑:程序博客网 时间:2024/06/05 17:10
【问题描述】设编号为 1 , 2 , ……, n 的 n ( n >0 ) 个人围成一个圈,每人持有一个密码 m ,从 数,报到 m 时停止报数,报 m 的出圈,……,如此下去,直到所有人全部出圈为止。当 任意给定 n 和 m 后,设计算法求 n 个人出圈的次序。 
 
【数据结构分析】
由于约瑟夫环本身问题具有循环性质,考虑用循环链表解决该问题。 


【问题分析】 

建立单链表后,通过初始密码找到出列的结点,输出该结点的序号, 将该结点中的密码值作为下一轮的初始密码,将该结点从链表中删除, 并释放该结点的空间。重复此过程,直到剩下最后一个结点,就直接将该结点中的序号删除, 删除该结点,并释放该结点的空间。 


/* 约瑟夫环问题(Josephus)*/#include <stdio.h>#include <stdlib.h>// 链表节点typedef struct _RingNode{    int pos;  // 位置    struct _RingNode *next;}RingNode, *RingNodePtr;// 创建约瑟夫环,pHead:链表头指针,count:链表元素个数void CreateRing(RingNodePtr pHead, int count){    RingNodePtr pCurr = NULL, pPrev = NULL;    int i = 1;    pPrev = pHead;    while(--count > 0)    {        pCurr = (RingNodePtr)malloc(sizeof(RingNode));        i++;        pCurr->pos = i;        pPrev->next = pCurr;        pPrev = pCurr;    }    pCurr->next = pHead;  // 构成环状链表}void PrintRing(RingNodePtr pHead){    RingNodePtr pCurr;    printf("%d", pHead->pos);    pCurr = pHead->next;    while(pCurr != NULL)    {        if(pCurr->pos == 1)            break;        printf("\n%d", pCurr->pos);        pCurr = pCurr->next;    }}void KickFromRing(RingNodePtr pHead, int m){    RingNodePtr pCurr, pPrev;    int i = 1;    // 计数    pCurr = pPrev = pHead;    while(pCurr != NULL)    {        if (i == m)        {            // 踢出环            printf("\n%d", pCurr->pos);    // 显示出圈循序            pPrev->next = pCurr->next;            free(pCurr);            pCurr = pPrev->next;            i = 1;        }        pPrev = pCurr;        pCurr = pCurr->next;        if (pPrev == pCurr)        {            // 最后一个            printf("\n%d", pCurr->pos);    // 显示出圈循序            free(pCurr);            break;        }        i++;    }}int main(){    int m = 0, n = 0;    RingNodePtr pHead = NULL;    printf("---------------Josephus Ring---------------\n");    printf("N(person count) = ");    scanf("%d", &n);    printf("M(out number) = ");    scanf("%d", &m);    if(n <= 0 || m <= 0)    {        printf("Input Error\n");        system("pause");        return 0;    }    // 建立链表    pHead = (RingNodePtr)malloc(sizeof(RingNode));    pHead->pos = 1;    pHead->next = NULL;    CreateRing(pHead, n);    #ifdef _DEBUG    PrintRing(pHead);    #endif    // 开始出圈    printf("\nKick Order: ");    KickFromRing(pHead, m);        printf("\n");}


0 0