c++循环列表解决约瑟夫环问题

约瑟夫环问题
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
编程思路:先建立一个循环链表,找到第一个报数的人,依次列出出列人的序号。
#include 
using namespace std;

struct Node
{
	int id;
	Node *next;
	Node(int i) { id = i; next = NULL; }
};
struct LinkedList
{
	Node *head;
	int length;
	LinkedList(){ head = NULL; length = 0; }
};
/************************************************************************/
/*  n 为总人数                                                          */
/*  k 为第一个开始报数的人                                              */
/*  m 为出列者喊到的数                                                   */
/************************************************************************/
void Josephus(int n, int k, int m)
{
	if (n<0||k<0||m<0)
	{
		cout << "三个输入参数必须都为正整数" << endl;
		return;
	}
	if (n < k)
	{
		cout << "起始序号必须大于总人数" << endl;
		return;
	}
	//先建立循环链表
	LinkedList *list = new LinkedList();
	Node *node = list->head;
	Node *pnode = list->head;  //先驱节点
	for (int i = 1; i <= n; i++)
	{
		if (i == 1)
		{
			node = new Node(i);
			list->head = node;
			list->length++;
			node->next = node;
		}
		else
		{
			pnode = node;
			node = new Node(i);
			pnode->next = node;
			node->next = list->head;
			list->length++;
		}
	}
	//打印下,验证现有链表信息正确
	Node *temp = list->head;
	for (int i = 1; i <= n; i++)
	{
		cout << temp->id << ends;
		temp = temp->next;
	}
	cout << endl;
	
	node = list->head;
	pnode = list->head;
	//找到第一个开始报数的人
	while (--k)
	{
		pnode = node;
		node = node->next;
	}
	cout << "第一个开始报数的人的id:" << node->id << endl;
	int j = m - 1;
	cout << "出列人的id依次是:" << ends;
	while (n--)
	{
		for (j = m-1; j > 0; j--)
		{
			pnode = node;
			node = node->next;
		}
			cout << node->id << " " << ends;
			pnode->next = node->next;
			node = pnode->next;
	}
}

void main()
{
	Josephus(5, 3, 1);
	cout << endl;
	Josephus(5, 3, 2);
	cout << endl;
	Josephus(9, 2, 3);
}


你可能感兴趣的:(c++循环列表解决约瑟夫环问题)