约瑟夫环问题

用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序(约瑟夫环问题)

 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序

[cpp] view plaincopy
 
  1. // 用户输入M,N值,从1至N开始顺序  
  2. // 循环数数,每数到M输出该数值,  
  3. // 直至全部输出  
  4. #include <stdio.h>  
  5.   
  6. // 节点  
  7. typedef struct node  
  8. {  
  9.     int data;  
  10.     node* next;  
  11. }node;  
  12.   
  13. // 创建循环链表  
  14. void createList(node*& head, node*& tail, int n)  
  15. {  
  16.     if(n<1)  
  17.     {  
  18.         head = NULL;  
  19.         return ;  
  20.     }  
  21.     head = new node();  
  22.     head->data = 1;  
  23.     head->next = NULL;  
  24.      
  25.     node* p = head;  
  26.     for(int i=2; i<n+1; i++)  
  27.     {  
  28.         p->next = new node();  
  29.         p = p->next;  
  30.         p->data = i;  
  31.         p->next = NULL;  
  32.     }  
  33.      
  34.     tail = p;  
  35.     p->next = head;  
  36. }  
  37.   
  38. // 打印循环链表  
  39. void Print(node*& head)  
  40. {  
  41.     node* p = head;  
  42.      
  43.     while(p && p->next!=head)  
  44.     {  
  45.         printf("%d ", p->data);  
  46.         p=p->next;  
  47.     }  
  48.     if(p)  
  49.     {  
  50.         printf("%d ", p->data);  
  51.     }  
  52. }  
  53.   
  54. // 用户输入M,N值,从1至N开始顺序  
  55. // 循环数数,每数到M输出该数值,  
  56. // 直至全部输出  
  57. void CountPrint(node*& head, node*& tail, int m)  
  58. {  
  59.     node* cur = head;  
  60.     node* pre = tail;  
  61.      
  62.     int cnt = m-1;  
  63.     while(cur && cur!=cur->next)  
  64.     {  
  65.         if(cnt)  
  66.         {  
  67.             cnt--;  
  68.             pre = cur;  
  69.             cur = cur->next;  
  70.         }  
  71.         else  
  72.         {  
  73.             pre->next = cur->next;  
  74.             printf("%d ", cur->data);  
  75.             delete cur;  
  76.             cur = pre->next;  
  77.             cnt = m-1;  
  78.         }     
  79.     }  
  80.      
  81.     if(cur)  
  82.     {  
  83.         printf("%d ", cur->data);  
  84.         delete cur;  
  85.         head = tail = NULL;  
  86.     }  
  87.     printf(" ");  
  88. }  
  89.   
  90. int main()  
  91. {  
  92.     node* head;  
  93.     node* tail;  
  94.     int m;  
  95.     int n;  
  96.     scanf("%d", &n);  
  97.     scanf("%d", &m);  
  98.     createList(head, tail, n);  
  99.     Print(head);  
  100.     CountPrint(head, tail, m);  
  101. system("pause");  
  102.     return 0;  
  103. }  


 

约瑟夫环问题算法

已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编

号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报

数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全

部出列。
  例如:n = 9, k = 1, m = 5
 【解答】
  出局人的顺序为5, 1, 7, 4, 3, 6, 9, 2, 8。

链表方法
  这个就是约瑟夫环问题的实际场景,有一种是要通过输入n,m,k三

个正整数,来求出列的序列。这个问题采用的是典型的循环链表的数据

结构,就是将一个链表的尾元素指针指向队首元素。 p->link=head
  解决问题的核心步骤:
  1.建立一个具有n个链结点,无头结点的循环链表
  2.确定第1个报数人的位置
  3.不断地从链表中删除链结点,直到链表为空

/*约瑟夫环*/ 

[cpp] view plaincopy
 
    1. #include   <stdlib.h>   
    2. #include   <stdio.h>   
    3. typedef   struct   node   
    4. {   
    5.   int   data;   
    6.   struct   node   *next;   
    7. }LNode;   
    8.   
    9. main()   
    10. {   
    11.   LNode*   Create(int,int);   
    12.   LNode*   GetNode(LNode   *);   
    13.   int   Print(LNode   *,int);   
    14.   LNode   *p;   
    15.   int   n,k,m;   
    16.   do   
    17.   {   
    18.     printf   ( "输入总人数 ");   
    19.     scanf   ( "%d ",&n);   
    20.   }   
    21.   while   (n <=0);   
    22.   do   
    23.   {   
    24.     printf   ( "输入开始人的序号(1~%d) ",n);   
    25.     scanf   ( "%d ",&k);   
    26.   }   
    27.   while   (k <=0   ||   k> n);   
    28.   do   
    29.   {   
    30.     printf   ( "输入间隔数字 ");   
    31.     scanf   ( "%d ",&m);   
    32.   }   
    33.   while(m <=0);   
    34.   
    35.   p=Create(n,k);   
    36.   Print(p,m);   
    37.   return   0;   
    38. };   
    39.   
    40. LNode*   Create(int   n,int   k)/*创建循环链表*/   
    41. {   
    42.   int   start=k-1;   
    43.   LNode   *s,*p,*L=0,*t;   
    44.   if   (start==0)   start=n;   
    45.   while   (n!=0)   
    46.   {   
    47.     s=(LNode   *)malloc(sizeof(LNode));   
    48.     if   (L==0)   p=s;   
    49.     if   (n==start)   t=s;   
    50.     s-> data=n;   
    51.     s-> next=L;   
    52.     L=s;   
    53.     n--;   
    54.   }   
    55.   p-> next=L;   
    56.   return   t;   
    57. }   
    58.   
    59. LNode*   GetNode(LNode   *p)/*出队函数*/   
    60. {   
    61.   LNode   *q;   
    62.   for   (q=p;q-> next!=p;q=q-> next);   
    63.   q-> next=p-> next;   
    64.   free   (p);   
    65.   return   (q);   
    66. }   
    67.   
    68. Print(LNode   *p,int   m)/*输出函数*/   
    69. {   
    70.   int   i;   
    71.   printf   ( "出队编号:  ");   
    72.   while   (p-> next!=p)   
    73.   {   
    74.     for   (i=1;i <=m;i++)   
    75.       p=p-> next;   
    76.     printf   ( "%d   ",p-> data);   
    77.     p=GetNode(p);   
    78.   }   
    79.   printf( "%d  ",p-> data);   
    80.   return   0;   
    81. }   
原文地址:https://www.cnblogs.com/davidshi/p/3371480.html