`
aladdin_leon
  • 浏览: 118824 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

单循环链表解决约瑟夫环问题

阅读更多

     这几天为了准备笔试忙着复习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. }  

 

分享到:
评论
1 楼 liuborama 2011-02-26  
不错,复习

相关推荐

    用单循环链表实现约瑟夫环问题

    《使用单循环链表解决约瑟夫环问题》 约瑟夫环问题,作为一个经典的计算机科学问题,其核心在于模拟一种淘汰机制。在这个问题中,n个人按照顺时针方向围成一个圆圈,从第1号开始报数,每报到m就出圈,然后从下一个...

    约瑟夫环实验 建立单循环链表

    【约瑟夫环实验与单循环链表】 约瑟夫环问题是一个经典的...总的来说,这段代码通过单循环链表实现了约瑟夫环问题的模拟,其中涉及到了链表的插入、删除和遍历等基本操作,展示了数据结构在解决实际问题中的应用。

    VC++2012编程演练数据结构《2》单循环链表与约瑟夫问题

    VC++2012编程演练数据结构《2》单循环链表与约瑟夫问题

    用链表表示循环链表的约瑟夫环的问题的源代码的报告

    2. 构建链表:根据人数创建一个单循环链表,每个节点代表一个人。 3. 游戏过程:设置一个计数器,从指定位置开始计数,每数到m就删除当前节点,然后从下一个节点继续计数,直至剩下一半的人数。 4. 循环检测:当删除...

    循环链表实现约瑟夫环

    在计算机科学中,循环链表被广泛应用于各种算法和数据结构的设计,其中一个著名的应用就是约瑟夫环问题。 约瑟夫环问题是一个经典的理论问题,源于古罗马时期的传说。假设有一群人围成一个圈,从某个人开始报数,每...

    约瑟夫环单循环链表C语言实现

    ### 约瑟夫环单循环链表C语言实现 #### 背景与问题描述 约瑟夫环(Josephus Problem)是一个经典的数学问题,最早由Flavius Josephus在公元前1世纪提出。该问题的基本形式是:N个人围成一个圈,从第一个人开始报数...

    约瑟夫环单循环链表的实现

    约瑟夫环单循环链表的实现 在计算机科学中,约瑟夫环是一个经典的问题,该问题是指在一个圆圈中,n个人排成一圈,每个人都有一个密码,编号从1到n。现在,编号为m的密码将被点名,并将其从圆圈中删除,然后继续下一...

    单循环链表与约瑟夫问题模拟(java)

    单循环链表是一种常见的数据结构,它在计算机科学中被广泛用于实现各种算法和数据管理。与普通链表不同,单循环链表的最后一个节点指向第一个节点,形成一个环状结构,使得遍历更加灵活。在Java编程语言中,我们可以...

    单链表实现约瑟夫环

    单链表解决约瑟夫环问题

    用C++做的单循环链表简单表示约瑟夫问题

    7. **递归解决方案**:虽然这里提到的是使用单循环链表,但约瑟夫问题也可以用递归方式解决,通过模拟每个节点的生存情况,直到只剩下一个节点。 8. **优化策略**:对于大规模的数据,可以考虑使用更高效的数据结构...

    C++ 中循环链表和约瑟夫环

    单链表只有向后结点,当单链表的尾链表不指向NULL,而是指向头结点时候,形成了一个环,成为单循环链表,简称循环链表。当它是空表,向后结点就只想了自己,这也是它与单链表的主要差异,判断node-&gt;next是否等于head...

    单循环链表求解约瑟夫问题

    有20个人排成一个圈,从第1个人开始循环报数,报到3或者3的倍数的离开圈子; 请编程计算并输出最后剩下三个人时是哪几个人。

    单项链表模拟约瑟夫环

    解决问题的关键在于找到合适的算法来模拟报数的过程。在代码中,主要采用了如下步骤: 1. **初始化链表**:根据输入的人数创建链表。 2. **报数过程**:从链表的第一个节点开始,按照指定的步长报数。每报数一轮,就...

    用C语言编写的约瑟夫环程序

    该程序以C语言实现的约瑟夫环问题,通过单循环链表结构有效地模拟了这一过程。用户可以输入人数n和初始报数上限m,以及每个人对应的密码,程序将按约瑟夫环规则输出出列顺序。程序设计清晰,逻辑严谨,是理解链表...

    数据结构 约瑟夫环源文件

    约瑟夫环问题旨在寻找一种有效的方法来模拟并解决这一问题。 在这个问题的解决方案中,数据结构的选择至关重要。常见的数据结构包括数组、链表以及栈等。数组由于其连续存储的特点,查找和删除元素效率较低,不太...

    数据结构循环链表解决约瑟夫问题(C++实现

    一个旅行社要从n个旅客中选出一名旅客,为他提供免费的环球旅行服务。旅行社安排这些旅客围成一个圆圈,从帽子中取出一张纸条,用上面写的正整数m()作为报数值。游戏进行时,从第s个人...其中数据结构采用单循环链表。

    数据结构课程设计报告—敢死队的问题.doc

    这个报告提供了一个清晰的步骤来使用单循环链表解决约瑟夫环问题,展示了数据结构在解决实际问题中的应用。尽管报告中没有提到其他数据结构的实现方式,但是可以考虑使用数组或动态数组,或者更高级的数据结构如栈或...

    C语言“约瑟夫环”问题实现

    下面我们将深入探讨如何用C语言解决约瑟夫环问题: 1. **问题定义**:假设n个人按顺时针方向站成一个圈,从第一个人开始报数,每数到m的人将被剔除,然后从下一个人继续报数,直至只剩下最后一个人为止。 2. **...

    C语言课程设计—约瑟夫环.doc

    在我们的课程设计中,我们将使用单循环链表来解决约瑟夫环问题。我们首先创建一个链表,其中每个结点的数据域的值为生成结点时的顺序号和每个人持有的密码。然后,我们使用一个指针current指向当前的结点,指针front...

Global site tag (gtag.js) - Google Analytics