zoukankan      html  css  js  c++  java
  • 单循环链表解决约瑟夫环问题

    关键字: 链表 约瑟夫环

         这几天为了准备笔试忙着复习C语言,决定把当时学C时的一些经典问题再温习一下,当时啊,学的稀里糊涂的,呵呵,现在回头来仔细写一写代码,就算是纪念当时的个性十足的赵老师了吧!
        约瑟夫问题的:编号为1,2,....,N的N个人按顺时针方向围坐一圈,每人持有一个密码(正整数),一开始任选一个正整数作为报数上限值M,从第一个人开始按顺时针方向自1开始顺序报数,报到M时停止报数。报M的人出列,将他的密码作为新的M值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
         解决思路还是很简单的,主要是要会熟练运用单循环链表的数据结构,通过单循环链表模拟围坐的一圈人,然后根据相应的密码进行报数,然后删除相应的链表节点。下面是C代码:

    1. #include <stdio.h>    
    2.  #include <stdlib.h>    
    3.  #define MAX_NODE_NUM 100    
    4.  #define TRUE 1U    
    5.  #define FALSE 0U    
    6.   
    7.  typedef struct NodeType    
    8.  {    
    9.       int id;    
    10.       int cipher;     
    11.            struct NodeType *next;    
    12.  } NodeType;    
    13.   
    14.  /* 创建单向循环链表 */    
    15.  static void CreaList(NodeType **, const int);    
    16.  /* 运行"约瑟夫环"问题 */    
    17.  static void StatGame(NodeType **, int);    
    18.  /* 打印循环链表 */    
    19.  static void PrntList(const NodeType *);    
    20.  /* 得到一个结点 */    
    21.  static NodeType *GetNode(const intconst int);    
    22.  /* 测试链表是否为空, 空为TRUE,非空为FALSE */    
    23.  static unsigned EmptyList(const NodeType *);    
    24.   
    25.  int main(void)    
    26.  {    
    27.        int n, m;    
    28.             NodeType *pHead = NULL;    
    29.             while (1)    
    30.             {    
    31.                 printf("请输入人数n(最多%d个): ", MAX_NODE_NUM);    
    32.                 scanf("%d", &n);    
    33.                 printf("和初始密码m: ");    
    34.                 scanf("%d", &m);    
    35.                 if (n > MAX_NODE_NUM)    
    36.                 {    
    37.                     printf("人数太多,请重新输入!\n");    
    38.                     continue;    
    39.                 }    
    40.                 else    
    41.                     break;    
    42.             }    
    43.             CreaList(&pHead, n);    
    44.             printf("\n------------ 循环链表原始打印 -------------\n");    
    45.             PrntList(pHead);    
    46.             printf("\n-------------删除出队情况打印 -------------\n");    
    47.             StatGame(&pHead, m);    
    48. }    
    49.   
    50.  static void CreaList(NodeType **ppHead, const int n)    
    51.  {    
    52.             int i, iCipher;    
    53.             NodeType *pNew, *pCur;    
    54.             for (i = 1; i <= n; i++)    
    55.             {    
    56.                 printf("输入第%d个人的密码: ", i);    
    57.                 scanf("%d", &iCipher);    
    58.                 pNew = GetNode(i, iCipher);    
    59.                 if (*ppHead == NULL)    
    60.                 {    
    61.                     *ppHead = pCur = pNew;    
    62.                     pCur->next = *ppHead;    
    63.                 }    
    64.                 else    
    65.                 {    
    66.                     pNew->next = pCur->next;    
    67.                     pCur->next = pNew;    
    68.                     pCur = pNew;    
    69.                 }    
    70.             }    
    71.             printf("完成单向循环链表的创建!\n");    
    72. }    
    73.   
    74. static void StatGame(NodeType **ppHead, int iCipher)    
    75. {    
    76.             int iCounter, iFlag = 1;    
    77.             NodeType *pPrv, *pCur, *pDel;    
    78.             pPrv = pCur = *ppHead;    
    79.             /* 将pPrv初始为指向尾结点,为删除作好准备 */    
    80.             while (pPrv->next != *ppHead)    
    81.                 pPrv = pPrv->next;    
    82.             while (iFlag)    
    83.             {     
    84.                 for (iCounter = 1; iCounter < iCipher; iCounter++)    
    85.                 {    
    86.                     pPrv = pCur;    
    87.                     pCur = pCur->next;    
    88.                 }    
    89.                 if (pPrv == pCur)    
    90.                     iFlag = 0;    
    91.                 pDel = pCur; /* 删除pCur指向的结点,即有人出列 */    
    92.                 pPrv->next = pCur->next;    
    93.                 pCur = pCur->next;    
    94.                 iCipher = pDel->cipher;    
    95.                 printf("第%d个人出列, 密码: %d\n", pDel->id, pDel->cipher);    
    96.                 free(pDel);    
    97.             }     
    98.             *ppHead = NULL;     
    99.             getchar();   
    100. }    
    101.   
    102. static void PrntList(const NodeType *pHead)    
    103. {    
    104.             const NodeType *pCur = pHead;    
    105.             if (EmptyList(pHead))    
    106.                 return;    
    107.             do    
    108.             {    
    109.                 printf("第%d个人, 密码: %d\n", pCur->id, pCur->cipher);    
    110.                 pCur = pCur->next;    
    111.             } while (pCur != pHead);    
    112.             getchar();   
    113. }    
    114.   
    115. static NodeType *GetNode(const int iId, const int iCipher)    
    116. {    
    117.             NodeType *pNew;    
    118.             pNew = (NodeType *)malloc(sizeof(NodeType));    
    119.             if(!pNew)    
    120.             {    
    121.                 printf("Error, the memory is not enough!\n");    
    122.                 exit(-1);    
    123.             }    
    124.             pNew->id = iId;    
    125.             pNew->cipher = iCipher;    
    126.             pNew->next = NULL;    
    127.             return pNew;    
    128. }    
    129.   
    130. static unsigned EmptyList(const NodeType *pHead)    
    131. {    
    132.             if(!pHead)    
    133.             {    
    134.                 printf("The list is empty!\n");    
    135.                 return TRUE;    
    136.             }    
    137.             return FALSE;    
    138. }  
  • 相关阅读:
    HDU
    hdu-1260 tickets
    hdu-1024 Max Sum Plus Plus
    spfa+链式前向星模板
    kafka-伪集群搭建
    elasticsearch-安装-centos7- es7.5 搭建
    elk-安装 通过docker
    kibana-安装-通过docker
    logstash -grok插件语法介绍
    docker 启动redis/nginx
  • 原文地址:https://www.cnblogs.com/alamps/p/1690525.html
Copyright © 2011-2022 走看看