josephus问题用链表来实现

来源:互联网 发布:mac sogo输入法 编辑:程序博客网 时间:2024/05/21 06:53

问题:有一群小孩围成一圈,从第s个小孩开始报数,报到m的时候出局,下一个小孩继续从1开始报数。到m再出局,反复直到只剩下一个小孩。写出出局的序列。

我的思路:

1.需要构造一个环形链表,这里采用了加1取模的方式来构造。point->next=josephus+i%m.这个方法对于环形链表来说是很实用的。

2.while的循环条件point->Next!=point.其实也就是说链表里面不止一个节点的情况。也就是说还没到游戏结束的情况。

3.程序的关键在于while循环内,有两个指针,point是要用来定位要删除节点的指针,而cut_point是用来定位point前面一个位置。当我们找到要剔除的节点的时候,只需要cut_point->next=point->next。就可以啦。

4.删除了以后记得这一句point=cut-point。这样能重新定位point的位置了。

5.如果不是从第一个小孩开始,而是从第S个小孩,1<S<=n.则最初的point应该这样定位:point=&josephus[s-1].

结构体编程:

#include<iostream>

#include<string>

using namespace std;

 struct Children

{

   int number;

   Children*next;

};


void show(Children*point,int num)//环链输出函数

{

   for(int i=1;i<=num;i++)

    {

         cout<<point->number<<",";

             point=point->next;

        }

}

void main()

{

  int num;//孩子总数

  int interval;//抽选号码

  int s;//从第几个还是开始报数

  cout<<"请输入孩子总数:";

  cin>>num;

  cout<<"请输入抽选号码:";

  cin>>interval;

  cout<<"请输入从第几个孩子开始报数:";

  cin>>s;

  Children *josephus=new Children[num];//新建一个结构体数组,并把起始地址赋给了josephus

  Children*point =josephus;//用于初始化链表的指针,起始地址与josephus指针相同

  for(int i=1;i<=num;i++)

  {

    point->number=i;

    point->next=josephus+i%num;//利用+1取模的方式设置节点的next指针,当道最后的时候自动指向到第一个,形成环链。

    point=point->next;

   }

    show(point,num);//输出这个链表。


    Children*cut_point;

   if(s==1)

    point=&josephus[num-1];//把起始指针设置在最后一个节点,当进入循环的时候就会从0开始,这样好让不需要的节点脱离。

   else 

    point=&josephus[s-2];

     int k=0;//故意设置一个k观察while循环了多少次。

     while(point->next!=point)//循环条件,通过循环不断寻找需要放弃的点

    {

      k++;

      for(int i=0;i<interval;i++)//其实这句话的作用在于将point指针移动到要删除的那个位置。数了interval次,就移动了                                               interval次。

      {

        cut_point=point;//储存截断位置的指针

        point=cut_point->next;//将point的指针移动到放弃的节点位置,此处也和while循环终止条件有关系。

      }

      cut_point->next=point->next;//将截断出的next指针设置成放弃处节点的next指针,使放弃处节点也就是不需要的节点脱离。

     cut_point=point;

    }

    cout<<"k:"<<k<<endl;

     cout<<"\n最后的赢家:"<<endl<<point->number<<endl<<point<<endl<<point->next<<endl;

     delete[]josephus;

     cin.get();

     cin.get();

}

原创粉丝点击