约瑟夫问题的C++实现

[复制链接]
1132|3
 楼主| 韩山童 发表于 2016-12-27 15:16 | 显示全部楼层 |阅读模式
C++, se, os, ST, nex
问题描述:
有n个小孩围成一圈,将他们从1开始依次编号,从编号为1的小孩开始报数,数到m的小孩出列,然后从出列的下一个小孩重新开始报数,数到m的小孩又出列,如此反复,直到所有的小孩全部出列为止,求整个出列序列。例如,n=6,m=5,则出列序列是:5,4,6,2,3,1。

办法:使用一个循环单链表表示小孩围成一圈。然后从编号为1的节点开始计数,计数到m时,将对应的节点从单链表中移除,同时输出该节点的编号。
(1)节点的存储结构:
  1. typedef struct _ListNode
  2. {
  3.     size_t number;
  4.      _ListNode *next;
  5. }ListNode;


(2)设计一个Joseph类,其中包括mTotal(对应n),mStart(对应m)整型变量和首节点指针mHead,构造函数用于建立长度为mTotal的循环单链表。保护成员函数JosephSequence用于输出约瑟夫序列。析构函数不做任何工作。
具体代码如下:
  1. #ifndef JOSEPH_H
  2. #define JOSEPH_H

  3. #include <stdio.h>
  4. typedef struct _ListNode
  5. {
  6.     size_t number;
  7.      _ListNode *next;
  8. }ListNode;

  9. class Joseph
  10. {

  11.     private:
  12.         Joseph()
  13.         {

  14.         }

  15.     public:
  16.         Joseph(size_t total,size_t start);
  17.         virtual ~Joseph();
  18.         void printJsequence();
  19.     protected:
  20.         void JosephSequence();
  21.     private:
  22.         size_t mTotal;
  23.         size_t mStart;
  24.         ListNode* mHead;
  25. };

  26. Joseph::Joseph(size_t total,size_t start)
  27. {
  28.     mTotal = total;
  29.     mStart = start;
  30.     ListNode *r,*p;
  31.     mHead = new ListNode();
  32.     mHead->next = nullptr;
  33.     mHead->number = 1;
  34.     r = mHead;

  35.     //建立单链表,包含mTotal个节点
  36.     for (size_t i=2; i <= mTotal; ++i)
  37.     {
  38.         p = new ListNode();
  39.         p->number = i;
  40.         r->next = p;
  41.         r = p;
  42.     }

  43.     r->next = mHead;  //将链表连成循环链表

  44. }

  45. void Joseph::printJsequence()
  46. {
  47.     JosephSequence();
  48. }

  49. //输出约瑟夫序列
  50. void Joseph::JosephSequence()
  51. {

  52.     ListNode *p,*q;
  53.     size_t j = 1;
  54.     for (size_t i=1; i <= mTotal; ++i)
  55.     {
  56.         j = 1;
  57.         p = mHead;
  58.         while (j < mStart-1)//从1数到mStart
  59.         {
  60.             p = p->next;
  61.             ++j;
  62.         }

  63.         q = p->next;  //q是第mStartge节点,将该节点从循环单链表中移除
  64.         p->next = q->next;
  65.         printf("%d ",q->number);
  66.         delete q;
  67.         q = nullptr;
  68.         mHead = p->next;
  69.     }
  70. }

  71. Joseph::~Joseph()
  72. {

  73. }
  74. #endif // JOSEPH_H


测试:
  1. #include "Joseph.h"
  2. int main()
  3. {
  4.     Joseph jo(6,5);
  5.     jo.printJsequence();
  6.     return 0;
  7. }


输出:5 4 6 2 3 1
Meyeah 发表于 2016-12-27 15:27 | 显示全部楼层
看不懂,好像学C语言的时候那些例程用的不是这种方法吧
 楼主| 韩山童 发表于 2016-12-27 16:44 | 显示全部楼层
Meyeah 发表于 2016-12-27 15:27
看不懂,好像学C语言的时候那些例程用的不是这种方法吧

你也可以用C语言实现,很简单的
航天的鱼 发表于 2016-12-27 16:50 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

43

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部