【数据结构】1-2 约瑟夫环问题
发布时间:2021-03-31 14:54:01 所属栏目:安全 来源:网络整理
导读:副标题#e# 这里放出两种不同的代码,一个是老师给的(较为复杂),还有一个是自己写的。 自己写的: #includeiostreamusing namespace std;struct Node { int data; //数据单元 Node *link; //指向下一个结点};class Josephus{private: Node *head,*current
|
副标题[/!--empirenews.page--]
这里放出两种不同的代码,一个是老师给的(较为复杂),还有一个是自己写的。 自己写的: #include<iostream>
using namespace std;
struct Node {
int data; //数据单元
Node *link; //指向下一个结点
};
class Josephus
{
private:
Node *head,*current; //head是头结点,current指向当前结点
int sum;//存储链表中元素的个数
public:
Josephus(); //无参构造函数,全部初始化为空
Josephus(int Snumber,int strnumber);//有参构造函数,Snumber为总数,strnumber为开始序号
~Josephus();//析构函数
void del(Node *&p);
void select(int num);//num为间隔数
void print();
};
Josephus::Josephus()
{
current = NULL;
head = NULL;
sum = 0;
}
Josephus::Josephus(int Snumber,int strnumber)
{
sum = Snumber;
head = new Node;
head->data = strnumber;
current = head;
int dt = strnumber + 1;
for (int i = 1; i < Snumber; i++)
{
Node *p;
p = new Node;
p->data = dt;
current->link = p;
current = p;
dt++;
}
current->link = head;
}
void Josephus::del(Node *&p)
{
Node *d = p->link;
p->link = p->link->link;
delete d;
}
void Josephus::select(int num)
{
int sont = 1;
Node *p = head;
while (sum!= 1)
{
if (sont % (num-1) == 0)
{
del(p);
sum--;
head = p;
}
sont++;
p = p->link;
}
}
void Josephus::print()
{
cout << "剩下的序号有:" << endl;
Node *p = head;
for (int i = 0; i < sum; i++)
{
cout << p->data << " ";
p = p->link;
}
cout << endl;
}
Josephus::~Josephus()
{
/*Node *p = head->link;
while (p!=head)
{
Node *de = p;
p = p->link;
delete de;
}*/
head = NULL;
current = NULL;
}
测试代码: #include"LinkList.h"
int main()
{
int Snum,stnum,num;
cout << "请输入总数以及开始序号:";
cin >> Snum >> stnum;
Josephus A(Snum,stnum);
A.print();
cout << "请输入间隔数:";
cin >> num;
A.select(num);
A.print();
system("pause");
return 0;
}
其实原理很简单,就是通过循环链表不断循环然后删除就OK 标准代码: //Circle.h
#include<iostream>
using namespace std;
template<class T>
struct Node //结点结构
{
T data; //结点数据
Node*link;
Node() { link = NULL; }
Node(T e,Node*next = NULL)
{
data = e;
link = next;
}
};
template<class T>
class CircleLinkList
{ //不带表头结点的循环链表类
private:
Node<T> *current,*front; //current指向某结点,front指向current前驱
public:
CircleLinkList() :current(NULL),front(NULL) {} //构建空循环链表
CircleLinkList(T *d,int mSize); //利用d数组元素构建循环链表
~CircleLinkList(); //析构函数
bool InsertAfter(const T&x); //在current所指结点之后插入x
bool RemoveCurrent(T&x); //删除current所指结点
void movenext(int n = 1); //current后移n次
T GetCurrentData() { return current->data; }
bool toLocatioin(T &t);//让current指向t结点,若没有则current不移动
void Output() const; //输出循环链表
};
class Joseph // 约瑟夫环类
{
private:
int numOfBoy; //圈中人数
int startPosition; //报数起始点
int interval; //报数间隔
public:
Joseph(int boys,int start,int m) :
numOfBoy(boys),startPosition(start),interval(m) {}//构造函数
void setNumOfBoy(int num) { numOfBoy = num; }//重置圈中人数
void setStartPosition(int start) { startPosition = start; }//重置起始点
void setInterval(int inter) { interval = inter; }//重置报数间隔
int GetWinner();//求得最终优胜者编号
void print(); //输出约瑟夫环
};
template<class T>
CircleLinkList<T>::CircleLinkList(T *d,int mSize)
{ //构造函数,将d数组中的mSize个元素创建循环链表
//采用前插法创建。
int i;
Node<T> *p;
current = new Node<T>;
current->data = d[mSize - 1];
front = current;
for (i = mSize - 2; i >= 0; i--)
{
p = new Node<T>(d[i],current);
current = p;
}
front->link = current;
}
template<class T>
CircleLinkList<T>::~CircleLinkList() //析构函数
{
while (current != front)//销毁循环链表
{
Node<T> *r = current;
current = current->link;
delete r;
}
delete current;
}
template<class T>
bool CircleLinkList<T>::InsertAfter(const T&x)
//在current所指结点之后插入x,current指向x结点
{
Node<T> *s = new Node<T>(x);
if (!s)return false;
if (!current) //原循环链表为空
current = front = s->link = s;
else //原循环链表非空
{
s->link = current->link;
current->link = s;
front = current;
current = s;
}
return true;
}
template<class T>
bool CircleLinkList<T>::RemoveCurrent(T&x) //删除current所指结点
{
if (!current)//循环链表为空
return false;
x = current->data;
if (current == front)//链表中只有一个元素
{
delete current;
current = front = NULL;
}
else
{
front->link = current->link;//修改链表指针
delete current;
current = front->link;
}
return true;
}
template<class T>
void CircleLinkList<T>::Output() const //输出循环链表
{
if (!current)//循环链表为空
return;
Node<T> *p = current;
do
{
cout << p->data << " ";
p = p->link;
} while (p != current);
cout << endl;
}
template<class T>
void CircleLinkList<T>::movenext(int k) //current后移k次
{
for (int i = 1; i <= k; i++)
{
front = current; // front后移
current = current->link; //current后移
}
}
template<class T>
bool CircleLinkList<T>::toLocatioin(T &t)
//将current指向元素为t的结点,若没有则current不移动
{
if (!current)//循环链表为空
return false;
Node<T> *current1 = current,*front1 = front;
while (current1->data != t) //寻找元素t
{
front1 = current1;
current1 = current1->link;
if (current1 == current)// 已寻找一圈没有元素为t的结点
return false;
}
current = current1; //current指向元素为t的结点
front = front1;
return true;
}
int Joseph::GetWinner()//获得最终优胜者
{
CircleLinkList<int> boys;
for (int i = 0; i < numOfBoy; i++)//创建循环链表,编号依次为1~numOfBoy
{
int temp = i + 1;
boys.InsertAfter(temp);
}
boys.toLocatioin(startPosition); //找到报数起点
cout << endl << "依次出列的小孩是:" << endl;
for (int i = 1; i < numOfBoy; i++) //numOfBoy-1个小孩出圈
{
int x;
boys.movenext(interval - 1); //报数
boys.RemoveCurrent(x); //出圈
cout << x << " "; //输出出圈编号
}
return boys.GetCurrentData(); //返回优胜者编号
}
void Joseph::print() //输出约瑟夫环
{
cout << "圈中人数:" << numOfBoy << endl;
cout << "报数起始点:" << startPosition << endl;
cout << "报数间隔:" << interval << endl;
}
(编辑:我爱故事小小网_铜陵站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


浙公网安备 33038102330570号