Josephus环问题

问题描述:n个人围成一个环,从第i个开始,由1到interval不断报数,凡报到interval的出列,直到环空为。出列的人按先后顺序构成一个新的序列。例如,n=8,i=2,interval=3.则输出序列为:4 7 2 6 3 1 5 8

代码如下:

#include <iostream>

#include <iomanip>

using namespace std;

struct Jonse  //定义单链表结构体

{int code;

 Jonse *next;

};

Jonse *Create(int);//声明创建链表函数

void ShowList(Jonse *);//声明表示输出链函数

void Out(Jonse*,int,int);//声明输出被删结点的号码的函数

int main()

{Jonse *head;

 int num,val,beg;//num是结点数目,val是间隔,beg是开始的位置

 cout<<"\nplease input the number of total:\n";

 cin>>num;//输入结点数目

 head=Create(num);//创建数目为num的链表

 ShowList(head);//表示输出链表

 cout<<"\nplease input the code of begin:\n";

 cin>>beg;//输入节点报数开始位置

 cout<<"\nplease input intervel of counting:\n";

 cin>>val;//输入报数间隔大小

 cout<<"the new list is:\n";

 Out(head,beg,val);//依次输出被删的结点号码

 system("pause");

}

Jonse *Create(int n)//创建链表

{Jonse *h,*p;

 int i;

 h=new Jonse;//h为头指针

 p=h;

 for(i=1;i<=n;i++)//p的作用是把n个链表赋值

 {p->code=i;

 if(i<n)

  {p->next=new Jonse;

   p=p->next;

  }

 }

 p->next=h;

 return h;

}

void ShowList(Jonse *h)//输出建好的链表

{Jonse *p;

 p=h;

 do

 {cout<<p->code<<'\t';

  p=p->next;

 }while(p!=h);

}

void Out(Jonse *h,int i,int d)  //*h是头指针,i是开始位置,d是间隔

{Jonse *p,*q;

 int k;

 p=h;

 for(q=h;q->next!=h;q=q->next);//把q指向头指针的前驱

 for(k=1;k<i;k++)//寻找最初开始的位置

 {q=p;

  p=p->next;

 }

 while(p!=p->next)//处理链环,直到最后一个结点

 {for(k=1;k<d;k++)//报数,输出

  {q=p;

   p=p->next;

  }

 cout<<p->code<<'\t';//输出被删的结点

 q->next=p->next;//删除结点

 delete p;

 p=NULL;

 p=q->next;

 }

 cout<<p->code<<endl;//输出最后一个结点

 delete p;

 p=NULL;

}

运行结果如下:

Josephus环问题


你可能感兴趣的:(Josephus环问题)