`
aladdin_leon
  • 浏览: 117521 次
  • 性别: 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,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人...

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

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

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

    约瑟夫环的问题描述 问题描述:编号为1,2… n的n个人按顺时针方向围坐一圈,每人持有...利用单循环链表作为存储结构模拟此过程; ⑵.键盘输入总人数、初始报数上限值m及各人密码; ⑶.按照出列顺序输出各人的编号。

    单链表实现约瑟夫环

    单链表解决约瑟夫环问题

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

    约瑟夫环问题描述:n个人围成一圈报数(每个人用编号1—n表示即可),从1号开始,每数到m出圈一个,然后再从下一个开始重新报数,直至所有人全部出圈为止。试设计一个程序求出圈顺序,要求n、m由键盘输入。

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

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

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

    数据结构问题,编程实现约瑟夫环,原题是严淑敏的《数据结构C语言版题集》实习一的第二题

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

    程序源代码: #include typedef struct Node { int num; int pasword;

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

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

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

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

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

    NULL 博文链接:https://128kj.iteye.com/blog/1613674

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

    本程序主要是以建立单循环链表的形式,利用单向循环链表存储结构模拟此过程,建立起一个约瑟夫环,然后根据之前创立的结点,输入结点里的一些数据,程序有主函数开始,首先,提示输入创建约瑟夫环环数以及每个环上所...

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

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

    yuesefu.rar_循环链表 约瑟夫

    约瑟夫环,利用单循环链表存储结构模拟此过程

    数据结构 约瑟夫环源文件

    约瑟夫环控制台程序,C/C++,Microsoft Visual Studio 2010工程,简单高效

    约瑟夫生者死者游戏(vc实现、c编写)

    问题描述:约瑟夫生者死者游戏:30个旅客同乘一条船,因为严重超载,非常危险,大家一致同意将一半的旅客投入海中。30个旅客围成一圈,由第一个人开始,依次报数,数到第9人,便...试用数组和单循环链表来解决本问题。

    约瑟夫环(链表实现)

    用单循环链表实现的约瑟夫环C++源代码,有详细注释。

    一个约瑟夫环的程序

    从1至m对带头结点的单循环链表循环计数,到m时,输出该结点的编号值,将该结点的密码作为新的m值,再从该结点的下一个结点起重新自1起循环计数;如此下去,直到单循环链表空时循环过程结束。输入的形式为一个以"回车...

    C++版约瑟夫环程序

    自己写的约瑟夫环C++小程序 用的数据结构是单循环链表 输入约瑟夫环的长度-1

    数据结构实验《约瑟夫环问题》

    数据结构实验《约瑟夫环问题》 #include"iostream.h" #define N 100 typedef struct node//采用数据类型定义 { int number; struct node *next; }Lnode,*LinkList; LinkList InitRingList(int n)//建立一个单循环...

Global site tag (gtag.js) - Google Analytics