循环链表示例:求解约瑟夫问题(C++实现)

约瑟夫问题描述:

一个旅行社要从n个旅客中选出一名旅客,为他提供免费的环球旅行服务。旅行社安排这些旅客围成一个圆圈,从帽子中取出一张纸条,用上面写的正整数m(

下面给出实现挑选环球旅行者的过程。函数Josephus用于选择,参数为旅客人数n,和报数值m。该函数过程共执行n-1躺报数循环(因为要淘汰n-1个人),每趟连续计数m项,并从链表中删去第m个结点以及打印该结点编号,当只剩一个结点时结束循环,结束算法。

#include"CircList.h"
template
void Josephus(CircList& Js,int n,int m){
	CircLinkNode *p=Js.getHead(),*start=Js.getHead(),*pre=NULL;
	for (int i = 0; i < n-1; i++){           //有n-1个人,报了n-1次,每次报了m个数
		for (int j = 1; j <=m; j++)          //按顺序循环遍历
		{
			pre=p;
			p=p->link;
			if (p->data==-1)                 //如果是附加头节点(附加头结点data已被赋值为1),则跳过
			{
				pre=p;
				p=p->link;
			}
		}
		cout<<"出列的人是:"<data<link=p->link;delete p;
		p=pre;
	}
}
int main(){
	const int first=-1;                     //标记附加头结点的data为-1
	CircList clist(first);
	int m,n;
	cout<<"输入游戏者人数和报数间隔:";
	cin>>n>>m;
	for (int i = n; i>=1; i--) 
		clist.Insert(0,i);
	Josephus(clist,n,m);
	return 0;
}

循环链表只实现需要用到的部分。

CircList.h

#include
using namespace std;
template
struct CircLinkNode                                           
{
	T data;
	CircLinkNode *link;
	CircLinkNode(CircLinkNode *next=NULL):link(next){}
	CircLinkNode(T d,CircLinkNode *next=NULL):data(d),link(next){}
};
template
class CircList
{
public:
	CircList(){first = new CircLinkNode;last=first;last->link=first;first->link=first;}
	CircList(const T& x){first = new CircLinkNode(x);last=first;last->link=first;first->link=first;}
	~CircList(){makeEmpty();}
	void makeEmpty();
	bool IsEmpty()const{return first->link==first?true:false;}
	CircLinkNode *getHead()const{return first;}
	void setHead(CircLinkNode *p){first=p;}
	CircLinkNode *Locate(int i);
	bool Insert(int i,T& x);
private:
	CircLinkNode *first,*last;
};
template
void CircList::makeEmpty(){
	CircLinkNode *q;
	while (first->link!=last->link)
	{
		q=first->link;
		first->link=q->link;
		delete q;
	}
}
template
CircLinkNode *CircList::Locate(int i){
	if (i<0)return NULL;
	CircLinkNode* current=first;
	int k=0;
	while (klink!=last->link)
	{
		k++;
		current=current->link;
	}
	return current;
}
template
bool CircList::Insert(int i,T& x){
	CircLinkNode* current=Locate(i);
	CircLinkNode *newNode=new CircLinkNode(x);
	if (newNode==NULL){cerr<<"存储分配错误!" <link=current->link;
	current->link=newNode;
	if (newNode->link==first)
		last=newNode;
	return true;
}


你可能感兴趣的:(数据结构)