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


      约瑟夫环问题可以简单的使用数组的方式实现,但是现在我使用循环链表的方法来实现,因为上午看到一道面试题规定使用循环链表解决约瑟夫环问题。

      什么是约瑟夫环?

      “约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。”(百度百科中的解决办法列出了很多,可以看到循环链表并不是最简单的方法)

      这道面试题考察了循环链表的“创建”,“遍历”和“删除”。

    创建的循环链表的结构图:

    解决约瑟夫环问题的过程

    C++实现代码如下:

    循环链表解决约瑟夫问题
     1 /**循环链表解决约瑟夫环问题
     2  * 问题:约瑟夫环
     3  * 有编号从1到N的N个人坐成一圈报数,从第K个人开始报数,报到M的人出局,
     4  * 下一位再从1开始报数,如此持续,直止剩下一位为止,报告此人的编号X。
     5  * 输入N,K,M,求出X。
     6  */
     7 
     8 #include <iostream>
     9 using namespace std;
    10 
    11 struct MyNode
    12 {
    13     MyNode(int a_data):m_data(a_data),m_pNext(NULL) {}
    14     
    15     int    m_data;
    16     MyNode *m_pNext;
    17 };
    18 
    19 class Josephus
    20 {
    21 public:
    22     Josephus(int a_N, int a_K, int a_M):m_N(a_N),m_K(a_K),m_M(a_M)
    23     {
    24         createList();
    25         outputList();
    26     }
    27     
    28 protected:
    29     void createList();
    30     void outputList();
    31     
    32 private:
    33     MyNode *m_pHead;//循环链表的头节点
    34     int    m_N;     //链表节点个数
    35     int    m_K;     //第一个报数人的序号
    36     int    m_M;     //报数出局的数
    37 };
    38 
    39 void Josephus::createList()
    40 {
    41     MyNode *pre = NULL;
    42     MyNode *cur = NULL;
    43     MyNode *p = new MyNode(1);
    44     m_pHead = p;
    45     cur = p;
    46     for (int i=2; i<=m_N; i++)
    47     {
    48         p = new MyNode(i);
    49         pre = cur;
    50         cur = p;
    51         pre->m_pNext = cur;
    52     }
    53     cur->m_pNext = m_pHead;
    54     
    55     int n=m_N;
    56     p = m_pHead;
    57     while (n--)
    58     {
    59         cout << p->m_data << ",";
    60         p = p->m_pNext;
    61     }
    62     cout << endl;
    63 }
    64 
    65 void Josephus::outputList()
    66 {
    67     MyNode *pre = NULL;
    68     MyNode *cur = m_pHead;
    69     m_K--;
    70     while (m_K--)            //寻找第K个人(开始报数的人)
    71     {
    72         pre = cur;
    73         cur = cur->m_pNext;
    74     }
    75     while (m_N--)            //输出链表中所有的节点值
    76     {
    77         int s = m_M-1;
    78         while (s--)            //寻找间隔M的人
    79         {
    80             pre = cur;
    81             cur = cur->m_pNext;
    82         }
    83         MyNode *p = cur;
    84         cout << p->m_data << ",";
    85         cur = cur->m_pNext;    //删除节点的过程
    86         pre->m_pNext = cur;
    87         delete p;
    88         p=NULL;
    89     }
    90 }
    91 
    92 int main()
    93 {
    94     Josephus josephus(100,5,5);
    95     return 0;
    96 }

    测试结果:

  • 相关阅读:
    优化算法-BFGS
    Go语言及Web框架Beego环境无脑搭建
    使用WCF扩展记录服务调用时间
    红黑树LLRB
    springmvc国际化 基于请求的国际化配置
    Adapter Pattern
    泡泡屏保
    使用WCF扩展在方法调用前初始化环境
    OAuth的一个.NET开源实现
    Google C++编程风格指南
  • 原文地址:https://www.cnblogs.com/hanxi/p/2718413.html
Copyright © 2020-2023  润新知