环形链表+约瑟夫问题实现

1.问题描述:

约瑟夫问题:

已知m个人还坐在桌子上,从第k个人开始进行报数,报道第n个人出列,直达所有的额人都出列为止,求出出列的顺序

2。数据结构:

我们根据题意可以明显的发现,如果我们用环形链表来进行处理的话每次出队一人是非常好实现的,我们判断终点的条件就是环形链表内的权值为0

在这里没什么好说的,我们只要注意一点就好了,有的书上并没有说明,但是当约瑟夫问题的头节点被删除之后,我们的要提前将头节点向后转移,不能出现头节点为空的情况

3.代码:

#include"iostream"
#include"cstdio"
#include"cstdlib"
#include"cstring"

using namespace std;

class point
{
	public:
		point(int n,point* p)
		{
			key=n;
			next=p;  //next指向和p相同 
		}
		int getkey()
		{
			return key;
		}
		point*& returnnext()
		{
			return next;
		}
		point* next;
	private:
		int key;
};

class circlelist
{
	public:
		circlelist()
		{
			head=NULL;
			num=0;
		}
		~circlelist()
		{
			if(num==0) head=NULL;
			else
			{
				point* p=head->next;
	     		while(p!=head)
	    		{
    				head->next=head->next->next;
    		    	free(p);
    			}
    			free(head);
    		}
   		}
		point* find(int i)
		{
			int k=1;
			point* p=head;
			while(k!=i)
			{
				p=p->next;
				k++;
			}
			return p;
		}
		void insert(int key,int i)
		{
			if(num==0)
			{
				head=new point(key,NULL);
				head->next=head;
				num++;
				return ;
			}
			point* k=find(i-1);
			point* help=new point(key,k->next);
			k->next=help;
			num++;
		}
		void delete_point(int i)
		{
			point* k=find(i-1);
			point* help=k->next;
			k->next=k->next->next;
			free(help);
			num--;
		}
		void delete_point(point* p)
		{
			if(p==head) 
			{
				while(p->next!=head) p=p->next;
				p->next=head->next;
				point* help=head;
				head=head->next;
				free(help);
				num--;
				return ;
			}
			point* k=head;
			while(k->next!=p) k=k->next;
			k->next=k->next->next;
			free(p);
			num--;
		}
		bool empty()
		{
			return num;
		}
		void print()
		{
			point* p=head;
			cout<<p->getkey()<<' ';
			p=p->next;
			while(p!=head)
			{
				cout<<p->getkey()<<' ';
				p=p->next;
			}
			cout<<endl;
		}
	private:
		point* head;
		int num;
};

int main()
{
	circlelist my;
	cout<<"约瑟夫问题的个数"<<endl;
	int m;
	cin>>m;
	for(int i=1;i<=m;i++) my.insert(i,i);
	int k;
	int n;
	cin>>k>>n;
//	my.print();
	point* p=my.find(k);
	while(my.empty()!=0)
	{
		int count=1;
		while(count!=n)
		{
			count++;
			p=p->next;
		}
		point* help=p;
		cout<<help->getkey()<<' ';
		p=p->next;
		my.delete_point(help);
	}
	cout<<endl;
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值