首页 > 代码库 > 约瑟夫环问题

约瑟夫环问题

/*此方法是利用循环链表
#include <iostream>
using namespace std;
typedef struct _Node
{
	int element;
	_Node * next;
}Node;

//约瑟夫问题-n(1, 2,...n)个人,从第k个报数,报数到m的那个人出列,
//他的下一个人从1开始报数,报数到m的那个出列,以此类推
void Josephus(int n, int k, int m)
{
	//根据n创建循环链表
	Node * head = (Node *)malloc(sizeof(Node));  //头结点
	head->next = NULL;

	int i;
	Node * p = head;
	Node * pTemp = NULL;
    for (i = 0; i < n; i++)
    {
		pTemp = (Node *)malloc(sizeof(Node));
		pTemp->element = i + 1;  //编号从1开始
		pTemp->next = NULL;
		p->next = pTemp;
		p = pTemp;
    }
	p->next = head->next; //链表最后一个结点指向第一个节点

	//找到编号为k的节点
	p = head->next;
	Node * pre = head;
	while (p != NULL)
	{
		if (p->element == k)
		{
			break;
		}
		pre = p;
		p = p->next;
	}

	//按规则输出
	for (i = 0; i < n; i++)  //总共n个结点,需循环n次
	{
		for (int j = 0; j < m - 1;j++)  //从指针指向的那个节点开始报数,报数到m,所以循环m-1次
		{
			pre = p;
			p = p->next;
		}
		cout << p->element << " ";
		pre->next = p->next;
		free(p);
		p = pre->next;
	}
	free(head); //释放头结点
}
int main()
{
	Josephus(8,1,4);
	return 0;
}*/

//接下来是基础的C代码
#include<stdio.h>
#include<stdlib.h>
int main()
{
	int i,j,n,m,*p;
	scanf("%d%d",&n,&m);
	p=(int *)malloc(n*sizeof(int));
	for(i=0;i<n;i++)
		p[i]=i+1;
	i=0;
	while(n>1)
	{
		i=(i+m-1)%n;
		printf("%-4d",p[i]);
		for(j=i+1;j<n;j++)
			p[j-1]=p[j];
		n--;
		if(i==n)
			i=0;
	}

	printf("\n%d\n",p[0]);
	free(p);
	return 0;
}

约瑟夫环问题