你好

约瑟夫环的简单实现(C++链表)

 

约瑟夫环(Joseph Circle)

  编号为1,2,...,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。现在给定一个随机数m>0,从编号为1的人开始,按顺时针方向1开始顺序报数,报到m时暂停。报m的人出圈,同时留下他的密码作为新的m值,从他在顺时针方向上的下一个人开始,重新从1开始报数,如此下去,直至所有的人全部出列为止。

  

对应的密码为顺序为:4 8 9 15 22 1 3

 

  1 #include <iostream>
  2 using namespace std;
  3 
  4 typedef struct Node
  5 {
  6     int e;
  7     struct Node* next;
  8 }Node, *Linklist;
  9 //Linklist 一个节点的指针
 10 void initlist(Linklist &head)
 11 {
 12     int n;
 13     Linklist head_ptr,tail_ptr,temp;
 14     head = (Linklist)malloc(sizeof(Node));
 15     head->next = nullptr;
 16     head_ptr = head;
 17     tail_ptr = head;
 18     cout << "输入需要节点个数:";
 19     cin >> n;
 20     for (int i = 0; i < n; i++)
 21     {
 22         temp= (Linklist)malloc(sizeof(Node));    
 23         temp->next = nullptr;
 24         tail_ptr->next= temp ;
 25         cout << "" << i + 1 << "个节点:";
 26         cin >> temp->e;
 27         tail_ptr=tail_ptr->next  ;
 28     }
 29 
 30 }
 31 
 32 void show(Linklist list)
 33 {
 34     Linklist p = list;
 35     p = p->next;
 36     while (p != nullptr)
 37     {
 38         cout << p->e << endl;
 39         p = p->next;
 40     }
 41 }
 42 
 43 void remove(Linklist list)
 44 {    
 45     int n;
 46     printf("输入需要删除的节点:");
 47     cin >> n;
 48     Linklist p=list;
 49     while (p->next->e != n)
 50     {
 51         p = p->next;
 52     }
 53     Linklist t = p->next;
 54     p->next = p->next->next;
 55     free(t);
 56     printf("删除结果:\n");
 57     show(list);
 58 
 59 }
 60 
 61 void insert(Linklist& list) {
 62     int n,i=0;
 63     Linklist t = (Linklist)malloc(sizeof(Node));
 64     Linklist p = list;
 65     printf("输入插入的节点元素:");
 66     cin >> t->e ;
 67     printf("输入插入的位置:");
 68     cin >> n;
 69     p = p->next;
 70     while (1)
 71     {    
 72         if (i == n - 1)
 73         {
 74             break;
 75         }
 76         p = p->next;
 77         i++;
 78     }
 79     t->next = p->next;
 80     p->next = t;
 81     printf("插入结果:\n");
 82     show(list);    
 83 
 84 }
 85 
 86 void JosehpInit(Linklist list) //用来构建一个循环链表,假设每个节点的e就是该节点的密码,头节点也存放一个密码
 87 {    
 88     Linklist p;        //list就是该链表的头节点的地址
 89     list->e = 3;  //假设头节点作为一号节点,约瑟夫环开始的第1个节点,并将它的密码设置成3,循环列表的输入从第二号节点开始,一号是头节点,写在程序中
 90     p = list;        
 91     while (p->next != nullptr) { p = p->next; }
 92     p->next = list;//list为头节点,将头节点和尾结点连起来
 93 
 94 }
 95 
 96 void JosehpImpl(Linklist list)  
 97 {    
 98     Linklist p = list,t=nullptr;
 99     int m=4;   //假设初始的密码是5,这里要定义成4(密码-1)
100     while (p->next!=p)
101     {
102         p = p->next;
103         m--;
104         if (m == 1)//此时p指针的下一个人就是将要出去的人
105         {
106             t = p->next;    //一定要注意先后顺序!!!在这卡了半天看不出毛病
107 
108             m = p->next->e;  //先将key替换为将要出去的人的密码
109             cout << p->next->e << endl;
110             p->next = p->next->next;
111             free(t);
112         }
113         
114     }
115     cout << p->e;
116 }
117 
118 int main()
119 {
120     Linklist list;
121     initlist(list);
122     JosehpInit(list);
123     JosehpImpl(list);
124     return 0;
125 }

 

posted @ 2020-10-07 23:03  S_nA_tCH!  阅读(724)  评论(0)    收藏  举报