约瑟夫环问题

/*
约瑟夫环问题:
 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。
*/

#include<stdio.h>
#include<stdlib.h>

//链表节点
typedef struct _RingNode
{
	int pos;//位置
	struct _RingNode *next;
		
}RingNode,*RingNodePtr;

//创建约瑟夫环,pHead:链表头节点,count:链表元素个数
void CreateRing(RingNodePtr pHead, int count)
{
	RingNodePtr pCurr=NULL,pPrev =NULL;
	int i=1;
	pPrev=pHead;
	while(--count > 0)
	{ 	
		pCurr=(RingNodePtr)malloc(sizeof(RingNode));
		i++;
 		pCurr->pos=i;
		pPrev->next=pCurr;
		pPrev=pCurr;
	}
   pCurr->next=pHead;	//构成环状链表	
}

void PrintRing(RingNodePtr pHead)
{
	RingNodePtr pCurr;
	printf("%d ",pHead->pos);
	pCurr=pHead->next;
	while(pCurr !=NULL)
	{
	     if(pCurr->pos==1)
	     {
		break;
	     }
	printf("\n%d",pCurr->pos);
	pCurr=pCurr->next;	
	}
}

void KickFromRing(RingNodePtr pHead,int m)
{
	RingNodePtr pCurr,pPrev;
	int i=1; //计数
	pCurr=pPrev=pHead;
	while(pCurr !=NULL)
	{
		if(i==m)
		{   //踢出环
		    printf("\n%d",pCurr->pos); //显示出圈循环顺序
		    pPrev->next=pCurr->next;
		    free(pCurr);
		    pCurr=pPrev->next;
		    i=1;
		}
	    pPrev=pCurr;
	    pCurr=pCurr->next;
	    if(pPrev ==pCurr)
	    {   //最后一个
		printf("\n%d",pCurr->pos);//显出出圈顺序
		free(pCurr);
 		break;
            }
	  i++;
	}
}

int main(void)
{
   int m=0,n=0;
   RingNodePtr pHead = NULL;
     printf("---------------Josephus Ring---------------\n");
      printf("N(person count) = ");
     scanf("%d", &n);
     printf("M(out number) = ");
     scanf("%d", &m);
     if(n <= 0 || m <= 0)
     {
         printf("Input Error\n");
         system("pause");
         return 0;	
     }
    //建立链表
      pHead = (RingNodePtr)malloc(sizeof(RingNode));
      pHead->pos = 1;
      pHead->next = NULL;
      CreateRing(pHead, n);
      #ifdef _DEBUG
      PrintRing(pHead);
      #endif
 
     // 开始出圈
     printf("\nKick Order: ");
     KickFromRing(pHead, m);    
     printf("\n");
     system("pause");
     return 0;
}

(以上是网上看的,下面是自己学习时的)

#include<stdio.h>
#include<stdlib.h>

#define N 10
#define TRUE 1
#define FALSE 0

typedef int data_t;
typedef struct node{
	data_t data;
	struct node *next;
}linknode ,*linklist;

void joseph(int n,int k,int m)
{
	linklist p,q;
	q=NULL;
	int i=1;
	q=p=(linklist)malloc(sizeof(linknode));
	q->data=i;
	for(i=2;i<=n;i++)
	{
		p->next=(linklist)malloc(sizeof(linknode));
		p=p->next;
		p->data=i;
	}
	p->next=q;//将链表连成一个环
	p=q;//让p指针回到第一个元素位置
	
	/*将指针q移到要开始的成员的前一个位置处*/
	for(i=1;i<k-1;i++)
	{
		q=q->next;
	}
	
	/*开始kill成员循环*/
	while(q->next !=q)//判断是不是环链表是不是只剩下一个元素的时候
	{
		for(i=1;i<m;i++)//开始按照间隔M个元素kill成员
		{
			q=q->next;
		}
		/*删除要找到的元素并打印出来*/
		p=q->next;
		q->next=p->next;
		printf("%d ",p->data);
		free(p);
	}
	printf("%d ",q->data);//打印最后一个元素
	printf("\n");
	return ;
}

int main(void)
{
	int a=N;//成员
	int k=2;//从第K个成员开始算起
	int m=3;//间隔m个成员开始kill成员
	joseph(a,k,m);
	
	return 0;
}









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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值