约瑟夫环

  1. 用单循环链表解决

约瑟夫问题用单链表解决时注意3中特殊情况:

(1)【count==m/count!=m时】p指针恰好指向L头结点时

(2)当pre指针恰好指向L头结点时

(3)当删除了报m的元素后,pre->next为头指针

本质问题:应保证pre,p指针指向的结点应有具体数值不是头结点

在这里插入图片描述

#include<stdio.h>
#include<stdlib.h> 
typedef struct Lnode
{
	int data;
	Lnode *next;
 } Lnode,*Linknode;
 void init(Linknode &L)
 {
 	L=(Linknode)malloc(sizeof(Linknode));
 	L->next=L;
 }
 void enter(Linknode &L,int e)
 {
 	Linknode s=(Linknode)malloc(sizeof(Lnode));
 	s->data=e;
 	Linknode p=L;
 	while(p->next!=L)
 	{
 		p=p->next;
	 }
	 s->next=p->next;
	 p->next=s;
 }
 bool delet(Linknode &L,Linknode p,Linknode pre)//删除链表中的第n个元素
 {
	pre->next=p->next;
	printf("%d   ",p->data);
	free(p);
	return true;
  } 
  int print(Linknode L)
  {
  	Linknode p=L->next;
  	int i=0;
  	while(p!=L)
  	{
  	//	printf("%d ",p->data);
  		i++;
  		p=p->next;
	  }
	  return i;
  }
  void cir(Linknode &L,int n,int m)   //约瑟夫环 
  {
  	int j=1;  //j:用于判断报的数
  	 for(int i=0;i<n;i++)
  	 {
  	 	enter(L,i+1);
	   }
	Linknode p=L->next,p1,pre=L;
	while(1)
	{
		if (print(L)==1)  //只剩下最后一个人 
			{
				printf("%d ",L->next->data);
				break;
			}
		if(j==m)
		{
			if(p==L)   //当j==m且指针指向头结点时 
			{
				p=L->next;
				pre=L;
			}
			delet(L,p,pre);
			if(pre->next==L)  
			{
				p=L->next;
			 } 
			 else
			 {
			 	p=pre->next;
			 }
			j=1;
		}
		else
		{
		
			if(p==L)
			{
				p=L->next;
				pre=L;
				j++;
			}
			else
			{
				p=p->next;
				j++;
				pre=pre->next;
			}
		}
	}
	   
  }
  void destory(Linknode &L)
  {
  	Linknode p=L->next,p1;
  	while(p->next!=L)
  	{
  		p1=p->next;
  		free(p);
  		p=p1;
	  }
	  free(p);
	  free(L);
  }
  int main()
  {
  	Linknode L;
  	init(L);
  	cir(L,5,3);
  	destory(L);
  	return 0;
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值