用单向循环链表解决约瑟夫问题

约瑟夫问题:设编号为1,2,...,n的n个人围成一圈,从编号为k的人从1开始计数,数到m的人出列,他的下一个人又从1开始计数,直到所有人出列。

解决思路:1.创建n个节点的循环链表  2.找到编号为k的人  3.开始计数,数到m时删除节点 4.从下一个节点重新计数,直到结束

#include
using namespace std;
typedef struct node
{
	int number;
	struct node * next;
}Node,*link;
link createlist(int n)//创建循环单向链表,返回头指针
{
	link head = NULL, tail = NULL;
	
	for (int i = 1; i <=n; i++)//编号从1开始
	{
		if (i == 1)
			head = tail = new Node;
		else
		{
			tail->next = new Node;
			tail = tail->next;
		}
		tail->number = i ;//设置新增节点编号
		//tail->next = NULL;
	}
	tail->next = head; 
	return head;
	
}
link deletenode(link s)//删除节点
{
	link p = s;
	while (p->next != s)//找到节点s
	{
		p = p->next;
	}
	p->next = s->next;
	free(s);
	return(p->next);
}
void josephu(link h, int n, int m, int k)
{
	int i = 1;
	while (i++ < k)
	{
		h = h->next;
	}
	while (n-- > 0)//循环n次
	{
		for (int j = 1; j < m; j++)
		{
			h = h->next;
		}
		cout << h->number<<" ";
		h = deletenode(h);
		cout << endl;
	}
}
void main()
{
	int n, m, k;
	while (1)
	{
		cin >> n >> m >> k;
		link head = createlist(n);
		josephu(head, n, m, k);
	}
	system("pause");
}

你可能感兴趣的:(用单向循环链表解决约瑟夫问题)