约瑟夫环

  1. 用单循环链表解决

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

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

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

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

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

约瑟夫环_第1张图片

#include
#include 
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;
  }

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