约瑟夫环——链表顺序表实现

需求分析 :对于任意给定的n,s,m求出列次序得到的n个人员的序列。
明确规定:设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m的人出列,然后从列出的下一个人重新开始报数,数到第m个人又出列,如此反复,直到所有的人出列为止。

输入形式、输入值的范围;n,m,s0<n、m、s<2147836473(int型的最大值)
输出形式;m1,m2,m3……
程序功能; 创建一个顺序表或链表,输入Josephus问题的三个n,m,s参数解决问题
测试数据(包括正确的输入和输出、错误的输入和输出)
正确:5,1,2
1,1,1
2,3,4(输入不合理,但是能够自动纠错,给出结果)
错误-1,0,2
1,0,2
2,2,0;

#include <iostream>
using namespace std;



typedef struct Linklist {

	int tableNumber;
	Linklist* next;
}linklist;
void CreatLinklist(linklist*& L, int n);
void ReturnTablename(int s, linklist* L, int n, int m);



class arrList {
private:
	int* aList;
	int m;//n个人
	int	len;//长度
	int Size;
public:
	arrList(const int size) {
		m = size;
		len = size - 1;
		Size = size;
		aList = new int[m];
		for (int i = 0; i < m; i++)
		{
			aList[i] = i + 1;

		}
	}
	void deleteM(int s, int m) {
		int x = 0;
		x = (s + m - 2 + Size) % Size;
		//int count=0;
		while (len > 0)
		{

			cout << aList[x] << " ";
			for (int i = x; i < len; i = (i + 1) % Size)
			{
				aList[i] = aList[i + 1];

			}

			len--;
			Size--;
			x = (x + m - 1) % Size;

			//cout << "s:"<<s<<" ";

		}
		cout << aList[0] << " ";

	}

};
//template <class T>
int main() {
	// your code goes here
	linklist* table;
	int n = 0;
	int s = 0;
	int m = 0;

	cout << "输入n,s,m" << endl;
	cin >> n >> s >> m;

	if (m < 1)
	{
		cout << "m必须大于0" << endl;
		return 0;
	}
	if (s < 1)
	{
		cout << "s必须大于0" << endl;
		return 0;
	}
	if (n < 1)
	{
		cout << "n必须大于0" << endl;
		return 0;
	}

	//arrList mylist(n);
	//mylist.deleteM(s, m);
	CreatLinklist(table, n);
	ReturnTablename(s, table, n, m);

	return 0;

}

void CreatLinklist(linklist*& L, int n) {
	//头节点
	L = new linklist;
	L->tableNumber = 1;
	L->next = L;
	linklist* head = L;
	for (int i = 1; i < n; i++)
	{
		linklist* S = new linklist;

		S->tableNumber = i + 1;
		head->next = S;
		head = S;
	}


	head->next = L;
}
void ReturnTablename(int s, linklist* L, int n, int m) {
	int count = 0;
	int delCount = 1;
	int x = m + s - 1;
	//cout << (s + m)  << endl;
	for (int i = 1; i < x - 1; i++)
	{
		L = L->next;

	}
	if (x == 1)
	{
		for (int i = 0; i < n; i++)
		{
			cout << L->tableNumber << ' ';

			L = L->next;
		}
	}
	else
	{

		cout << L->next->tableNumber << ' ';
		linklist* p;
		p = L->next;
		L->next = L->next->next;
		delete p;
		if (m == 1)
		{
			for (int i = 0; i < n; i++)
			{
				cout << L->tableNumber << ' ';

				L = L->next;
			}
		}
		else {

			while (L->next != NULL)
			{


				if ((count + 1) % n == m)
				{
					count = 0;
					delCount++;
					cout << L->next->tableNumber << ' ';
					linklist* p;
					p = L->next;
					L->next = L->next->next;
					delete p;
				}

				count++;
				if (delCount == n) {
					break;
				}
				L = L->next;
			}
		}

	}



}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值