【数据结构】C++代码实现 约瑟夫环

430 阅读2分钟
写在前面,可能有不少童鞋很疑惑为什么自己运行的时候会报错,这是因为自己的库中可能没有free函数,可以将free那行代码注释掉,应该可以正常的运行。此代码只是提供一个参考,代码还是要自己敲自己想,这样才能有提高的哦

Josephus环问题

问题描述:

约瑟夫(Joseph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。试设计一个程序求出出列顺序。

基本要求:

利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。

测试数据:

m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m值为6(正确的出列顺序应为6,1,4,7,2,3,5)。

代码:

#include<iostream>
using namespace std;

typedef struct lnode
{
	int data;
	int num;
	struct lnode* next;
}LNode, * LinkList;      //链表

LinkList Creat(int n)
{
	LinkList L = NULL;         //不带头结点的链表
	LNode* s, * r = NULL;
	int x;
	for (int i = 1; i <= n; i++)
	{
		LNode* s = new LNode;
		cin >> x;
		s->data = x;
		s->num = i;
		if (L == NULL) L = s;
		else r->next = s;
		r = s;
	}
	if (r != NULL) r->next = L;
	return L;
}

void Circle(LinkList& H, int m, int n)
{
	LinkList q, p = H;
	for (int j = 1; j <= n; j++)
	{
		for (int i = 1; i < m; i++)
		{
			p = p->next;
		}
		m = p->data;
		cout << p->num << " ";
		q = p->next;
		p->num = q->num;
		p->data = q->data;
		p->next = q->next;
		free(q);
	}
}

int main()
{
	int m, n;
	cout << "请输入人数" << endl;
	cin >> n;
	cout << "请按顺序输入各位的密码" << endl;
	LinkList L = new LNode;
	if (L == NULL) {
		cout<<"内存分配不成功!"<<endl;
	}
	else
	{
		L = Creat(n);
	}
	cout << "请给定第一个报数上限值" << endl;
	cin >> m;
	cout << "出列顺序如下" << endl;
	Circle(L, m, n);
	return 0;
}