1. 程式人生 > >演算法題-約瑟夫(Joseph)問題求解

演算法題-約瑟夫(Joseph)問題求解

題:編寫一個程式,求解約瑟夫(Joseph)問題。有n個小孩圍城一圈,將他們從1開始依次編號,從編號為1的小孩開始報數,數到第m個小孩出列,然後從出列的下一個小孩重新開始報數,數到第m個小孩有出列,如此反覆,直到所有的小孩全部出列為止,求整個出列序列。例如n=6,m=5是出列序列是5,4,6,2,3,1.

解:1、設計儲存結構:本題才迴圈單鏈表儲存小孩結點,

struct Child   //小孩結點型別
{
	int Num;
	Child* next;
};
由題可知,小孩圈迴圈單鏈表從第一個帶編號的小孩開始數,故迴圈單鏈表不帶頭結點。當n=6時,迴圈單鏈表如圖。

2、演算法設計

設計一個約瑟夫(Joseph)類,其中包含n,m整型變數和首結點指標h,建構函式用於建立有n個結點的不帶頭結點的迴圈單鏈表h,DisPlay()成員函式用於輸出約瑟夫序列,在每個結點出列時釋放,故解構函式不做任何工作。

#include<iostream>
using namespace std;
struct Child
{
	int Num;
	Child* next;
};
class Joseph
{
private:
	int n,m;
	Child *h;
public:
	Joseph(int n1,int m1);
	~Joseph();
	void DisPlay();
};

Joseph::Joseph(int n1,int m1)
{
	Child *p,*r;
	n=n1;
	m=m1;
	h=new Child();
	h->Num=1;
	r=h;
	for (int i=2;i<=n;i++)
	{
		p=new Child();
		p->Num=i;
		r->next=p;
		r=p;
	}
	r->next=h;
}
Joseph::~Joseph()
{

}
void Joseph::DisPlay()
{
	Child *p,*q;
	for (int i=1;i<=n;i++)
	{
		p=h;
		int j=1;
		while(j<m-1)
		{
			j++;
			p=p->next;
		}
		q=p->next;
		cout<<q->Num<<"\t";
		p->next=q->next;
		delete q;
		h=p->next;  //從下一個結點重新開始;
	}
}
驗證的主函式;
int main()
{
	Joseph obj(6,5);
	obj.DisPlay();
	return 0;
}