<数据结构> 约瑟夫问题 (待补充完整)------------代表ADT小组

一、约瑟夫问题

  假设n个依次顺序编号1,2,…,n的竞赛者排成一个环形队列。每人均持有一个密码m,从第1个人开始,从1开始循环计数,每数到第m时,则让让其出队列。然后从下一个人开始重新从1开始计数,继续进行下去。这个过程一直进行到所有的人都出队列为止。最后出列者为优胜者。请输出给定条件下出队列的顺序。

二、题目要求

    请结合第二章节:线性表相关内容,分析问题性质和操作方法,并完成代码编写。具体请完成如下内容:

    1.分析问题,问题实质可以理解为何种数据结构问题(逻辑结构问题)。

    2.根据分析,写出问题的ADT定义。

 3.确定数据的存储方法,并定义相关数据类型。

 4.描述实现的操作算法。

 5.写出完整代码,运行调试输出结果。

    必要时加上适当的图示。


分析题目得出,该问题用循环链表可解。



ADT Josephus

         Data:

                  每个数据元素类型相同。相邻元素具有前驱与后继关系,且第一个元素与最后一个元素互为前驱或后继。

         Operation:

                 Josephus

                             前置条件:线性表不存在

                            输入:无

                             功能:线性表的初始化

                             输出:无

                             后继条件:建立空线性表

                 m_Init:

                             前置条件:线性表(空)存在

                             输入:人数n,密码M

                             功能:线性表的初始化

                             输出:无

                             后继条件:创建一个有N个元素的循环链表

                 m_Run:

                             前置条件:线性表存在

                             输入:无

                             功能:循环计数,删除特定的元素

                             输出:无

                             后继条件:循环链表减少至剩下一个元素

                 m_Destroy:

                             前置条件:线性表存在

                             输入:无

                             功能:销毁线性表

                             输出:无

                             后继条件:释放内存                 

END ADT


//Josephus.h

#ifndef JOSEPHUS_H_
#define JOSEPHUS_H_
#include <iostream>
#include <iomanip>
using namespace std;

template <typename T>
struct Node
{
	T data;
	Node<T> *next;
};

template <typename T>
class Josephus
{
private:
	int m_length;
	Node<T> *head;
	int m_n;
	int m_m;
public:
	Josephus();
	void m_Init();                                     //设置游戏人数和游戏密码M
	void m_Run();                                     //出圈
	void m_Destroy();                                 //释放内存
	void m_Game();                                    //游戏
};

#endif

template <typename T>
Josephus<T>::Josephus()
{
	head = new Node<T>;
	head->next = NULL;
	m_length = 0;
	m_n = 0;
	m_m = 0;
}

template <typename T>
void Josephus<T>::m_Init()
{
	Node<T> *p, *q;
	q = head;
	if (head->next != NULL)
		head->next = NULL;
	cout << "请设置参加游戏的人数n(n > 0):";
	cin >> m_n;
		while (m_n <= 0)
		{
			cout << "游戏人数设置错误,请重新设置:";
			cin >> m_n;
		}
	for (int i = 0; i < m_n; i++)
	{
		p = new Node<T>;
		p->data = i + 1;
		q->next = p;
		q = p;
		q->next = head->next;
		m_length++;
	}
	cout << "\n人数设置完毕." << endl;
	cout << "\n请输入游戏密码M(M > 0):";
	cin >> m_m;
	while (m_m <= 0)
	{
		cout << "游戏密码设置错误,请重新设置:";
		cin >> m_m;
	}
	system("pause");                        //暂停
	system("cls");                       //清屏
}

template <typename T>
void Josephus<T>::m_Run()
{
	Node<T> *p, *q, *t;
	p = head->next;
	if (head->next == NULL)
		cout << "\n游戏出现异常,请确认是否设置了游戏人数和游戏密码" << endl;
	cout << "游戏者淘汰的编号和顺序:" << endl;
	while (p->next != NULL && p->next != p)
	{
		for (int i = 1; i < m_m - 1; i++)
			p = p->next;
		q = p;
		p = p->next;
		cout << p->data << '\t';
		q->next = q->next->next;
		t = p;
		p = p->next;
		delete t;
		m_length--;
	}
	cout << endl;
	cout << "\n游戏的胜利者的编号为" << p->data << endl;
}

template <typename T>
void Josephus<T>::m_Destroy()
{
	Node<T> *p, *q;
	p = head;
	q = p;
	for (int i = 0; i < m_length; i++)
	{
		q = q->next;
		delete p;
		p = q;
	}
	m_length = 0;
}

template <typename T>
void Josephus<T>::m_Game()
{
	this->m_Init();
	this->m_Run();
	this->m_Destroy();
}


//Josephus.cpp

#include "Josephus.h"
#include <iostream>
using namespace std;

int main()
{
	Josephus<int> jos;
	jos.m_Game();
	return 0;
}


实验结果:






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值