zoukankan      html  css  js  c++  java
  • 约瑟夫环问题

    【问题描述】设编号为 1 , 2 , ……, n 的 n ( n >0 ) 个人围成一个圈,每人持有一个密码 m ,从 数,报到 m 时停止报数,报 m 的出圈,……,如此下去,直到所有人全部出圈为止。当 任意给定 n 和 m 后,设计算法求 n 个人出圈的次序。 
     
    【数据结构分析】
    由于约瑟夫环本身问题具有循环性质,考虑用循环链表解决该问题。

    【问题分析】
    建立单链表后,通过初始密码找到出列的结点,输出该结点的序号, 将该结点中的密码值作为下一轮的初始密码,将该结点从链表中删除, 并释放该结点的空间。重复此过程,直到剩下最后一个结点,就直接将该结点中的序号删除, 删除该结点,并释放该结点的空间。 
     
    【程序代码(C语言)】
      1 /*
      2  约瑟夫环问题(Josephus)
      3 */
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 
      7 // 链表节点
      8 typedef struct _RingNode
      9 {
     10     int pos;  // 位置
     11     struct _RingNode *next;
     12 }RingNode, *RingNodePtr;
     13 
     14 // 创建约瑟夫环,pHead:链表头指针,count:链表元素个数
     15 void CreateRing(RingNodePtr pHead, int count)
     16 {
     17     RingNodePtr pCurr = NULL, pPrev = NULL;
     18     int i = 1;
     19     pPrev = pHead;
     20     while(--count > 0)
     21     {
     22         pCurr = (RingNodePtr)malloc(sizeof(RingNode));
     23         i++;
     24         pCurr->pos = i;
     25         pPrev->next = pCurr;
     26         pPrev = pCurr;
     27     }
     28     pCurr->next = pHead;  // 构成环状链表
     29 }
     30 
     31 void PrintRing(RingNodePtr pHead)
     32 {
     33     RingNodePtr pCurr;
     34     printf("%d", pHead->pos);
     35     pCurr = pHead->next;
     36     while(pCurr != NULL)
     37     {
     38         if(pCurr->pos == 1)
     39             break;
     40         printf("
    %d", pCurr->pos);
     41         pCurr = pCurr->next;
     42     }
     43 }
     44 
     45 void KickFromRing(RingNodePtr pHead, int m)
     46 {
     47     RingNodePtr pCurr, pPrev;
     48     int i = 1;    // 计数
     49     pCurr = pPrev = pHead;
     50     while(pCurr != NULL)
     51     {
     52         if (i == m)
     53         {
     54             // 踢出环
     55             printf("
    %d", pCurr->pos);    // 显示出圈循序
     56             pPrev->next = pCurr->next;
     57             free(pCurr);
     58             pCurr = pPrev->next;
     59             i = 1;
     60         }
     61         pPrev = pCurr;
     62         pCurr = pCurr->next;
     63         if (pPrev == pCurr)
     64         {
     65             // 最后一个
     66             printf("
    %d", pCurr->pos);    // 显示出圈循序
     67             free(pCurr);
     68             break;
     69         }
     70         i++;
     71     }
     72 }
     73 
     74 int main()
     75 {
     76     int m = 0, n = 0;
     77     RingNodePtr pHead = NULL;
     78     printf("---------------Josephus Ring---------------
    ");
     79     printf("N(person count) = ");
     80     scanf("%d", &n);
     81     printf("M(out number) = ");
     82     scanf("%d", &m);
     83     if(n <= 0 || m <= 0)
     84     {
     85         printf("Input Error
    ");
     86         system("pause");
     87         return 0;
     88     }
     89     // 建立链表
     90     pHead = (RingNodePtr)malloc(sizeof(RingNode));
     91     pHead->pos = 1;
     92     pHead->next = NULL;
     93     CreateRing(pHead, n);
     94     #ifdef _DEBUG
     95     PrintRing(pHead);
     96     #endif
     97     // 开始出圈
     98     printf("
    Kick Order: ");
     99     KickFromRing(pHead, m);    
    100     printf("
    ");
    101 }
    View Code
  • 相关阅读:
    Mapreduce实例-Top Key
    Mapreduce实例-分组排重(group by distinct)
    storm0.9.0.1升级安装
    mysql配置文件my.cnf详解
    MYSQL管理之主从同步管理
    一个经典实用的iptables shell脚本
    sed实例精解--例说sed完整版
    常用的主机监控Shell脚本
    Python(九)Tornado web 框架
    缓存、队列(Memcached、redis、RabbitMQ)
  • 原文地址:https://www.cnblogs.com/dingyichao/p/4021418.html
Copyright © 2011-2022 走看看