用单向环形链表实现约瑟夫环

        n个人围成一个环,从第一个人开始,有1至m不断报数,,凡报到m的出列,直到环中只剩下一个人为止,输出最后一个人的序号。
        如果要用链表实现,很容易想到要建立单向环形链表,及将尾节点中的next指针赋值为头节点的地址。然后从头节点开始遍历,如果遇到符合条件的节点,对其进行链表删除处理,并将n减1,直到n为1时停止遍历。
        下面是该问题的带有注释的完整代码:
#include
using namespace std;
int n, m, count;
struct Node
{
 int num;
 Node *next;
};                    //每个节点的结构
void Createlist(Node *&head)
{
 count = 0;
 cin >> n;
 Node *p = head;
 while (count != n)
 {
  Node *s = new Node;
  s->num = ++count;    //为每个节点标号
  if (head == NULL)
   head = s;
  else
   p->next= s;
  p = s;
 }
 p->next = head;   //将尾节点中的next赋值为头节点的地址,建立单向环形链表
}
int ans(Node *head)
{
 cin >> m;
 count = 0;
 while (n!=1)
 {
  count++;
  if ((count + 1) % m == 0)
  {
   Node *del = head->next;
   head->next = del->next;
   n--;
  }                                //进行链表中节点删除处理
 else
   head = head->next;
 }
 return head->num;         //返回剩下的一个人的序号
}
int main()
{
 Node *head = NULL;
 Createlist(head);
 cout << ans(head);
 return 0;
}
     其实,当进行节点删除处理时,如果等到count%3==0时在进行处理,会比较麻烦,但如果在(count+1)%3==0时进行处理,及当即将要删除的节点时当前所在节点的下一个节点时,会容易得多。

你可能感兴趣的:(用单向环形链表实现约瑟夫环)